public AttachmentProcessor(IEnumerable <ContentType> attachmentTypesToProcess, Func <IMailFolder, Func <MimePart, Func <IMessageSummary, string> > > fileNamer, AttachmentDownloader downloader, Func <ContentType, string, bool> isIgnorableAttachment, SearchQuery searchQuery, MessageSummaryItems fetchFlags ) { this.attachmentTypes = attachmentTypesToProcess; this.fileNamer = fileNamer; this.downloader = downloader; this.isIgnoreableAttachment = isIgnorableAttachment; if (searchQuery != null) { fetch = folder => { var messages = folder.Search(searchQuery); return(folder.Fetch(messages, fetchFlags)); }; } else { fetch = folder => folder.Fetch(0, -1, 0, fetchFlags); } }
public AttachmentProcessorBuilder() { attachmentTypes = new List <ContentType>(); downloadFolder = ""; fileNamer = folder => part => summary => ""; isIgnorableAttachment = (contentType, fileNamer) => false; searchQuery = null; fetchFlags = MessageSummaryItems.None; }
/// <summary> /// Fetch the message summaries for the messages between the two indexes (inclusive) /// that have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the messages between the two /// indexes (inclusive) that have a higher mod-sequence value than the one /// specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// </exception> /// <exception cref="System.ArgumentNullException"> /// <paramref name="fields"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <paramref name="fields"/> is empty. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="MailFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public abstract IList<IMessageSummary> Fetch (int min, int max, ulong modseq, MessageSummaryItems items, HashSet<string> fields, CancellationToken cancellationToken = default (CancellationToken));
/// <summary> /// Fetch the message summaries for the messages between the two indexes, inclusive. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the messages between the two /// indexes, inclusive.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// </exception> /// <exception cref="System.ArgumentNullException"> /// <paramref name="fields"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <paramref name="fields"/> is empty. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public abstract IList<IMessageSummary> Fetch (int min, int max, MessageSummaryItems items, HashSet<HeaderId> fields, CancellationToken cancellationToken = default (CancellationToken));
/// <summary> /// Fetch the message summaries for the specified message indexes that /// have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message indexes that /// have a higher mod-sequence value than the one specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="indexes">The indexes.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="indexes"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para>One or more of the <paramref name="indexes"/> is invalid.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public abstract IList<IMessageSummary> Fetch (IList<int> indexes, ulong modseq, MessageSummaryItems items, HashSet<HeaderId> fields, CancellationToken cancellationToken = default (CancellationToken));
/// <summary> /// Fetch the message summaries for the specified message indexes. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message indexes.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="indexes">The indexes.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="indexes"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para>One or more of the <paramref name="indexes"/> is invalid.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public abstract IList<IMessageSummary> Fetch (IList<int> indexes, MessageSummaryItems items, HashSet<string> fields, CancellationToken cancellationToken = default (CancellationToken));
public MessageNew(MessageSummaryItems messageSummaryItems, HashSet <HeaderId> fields) : base("MessageNew", true) { MessageSummaryItems = messageSummaryItems; Headers = ImapFolder.GetHeaderNames(fields); }
/// <summary> /// Fetches the message summaries for the messages between the two indexes, inclusive. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the messages between the two /// indexes, inclusive.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the IMAP server may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="items"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="ImapClient"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="ImapClient"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The <see cref="ImapFolder"/> is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch (int min, int max, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken)) { if (min < 0 || min > Count) throw new ArgumentOutOfRangeException ("min"); if (max != -1 && max < min) throw new ArgumentOutOfRangeException ("max"); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); CheckState (true, false); if (min == Count) return new IMessageSummary[0]; var query = FormatSummaryItems (ref items, null); var command = string.Format ("FETCH {0} {1}\r\n", GetFetchRange (min, max), query); var ic = new ImapCommand (Engine, cancellationToken, this, command); var ctx = new FetchSummaryContext (items); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = ctx; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Response != ImapCommandResponse.Ok) throw ImapCommandException.Create ("FETCH", ic); return AsReadOnly (ctx.Results.Values); }
/// <summary> /// Fetches the message summaries for the specified message UIDs that have a /// higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message UIDs that /// have a higher mod-sequence value than the one specified.</para> /// <para>If the IMAP server supports the QRESYNC extension and the application has /// enabled this feature via <see cref="ImapClient.EnableQuickResync(CancellationToken)"/>, /// then this method will emit <see cref="MailFolder.MessagesVanished"/> events for messages /// that have vanished since the specified mod-sequence value.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the IMAP server may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="uids">The UIDs.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="uids"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para>One or more of the <paramref name="uids"/> is invalid.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="ImapClient"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="ImapClient"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The <see cref="ImapFolder"/> is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="ImapFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch (IList<UniqueId> uids, ulong modseq, MessageSummaryItems items, HashSet<string> fields, CancellationToken cancellationToken = default (CancellationToken)) { var set = ImapUtils.FormatUidSet (uids); if (fields == null) throw new ArgumentNullException ("fields"); if (fields.Count == 0) throw new ArgumentException ("The set of header fields cannot be empty.", "fields"); if (!SupportsModSeq) throw new NotSupportedException ("The ImapFolder does not support mod-sequences."); CheckState (true, false); if (uids.Count == 0) return new IMessageSummary[0]; var query = FormatSummaryItems (ref items, fields); var vanished = Engine.QResyncEnabled ? " VANISHED" : string.Empty; var command = string.Format ("UID FETCH {0} {1} (CHANGEDSINCE {2}{3})\r\n", set, query, modseq, vanished); var ic = new ImapCommand (Engine, cancellationToken, this, command); var ctx = new FetchSummaryContext (items); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = ctx; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Response != ImapCommandResponse.Ok) throw ImapCommandException.Create ("FETCH", ic); return AsReadOnly (ctx.Results.Values); }
/// <summary> /// Fetches the message summaries for the messages between the two indexes, inclusive. /// </summary> /// <remarks> /// Fetches the message summaries for the messages between the two indexes, inclusive. /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// </exception> /// <exception cref="System.ArgumentNullException"> /// <paramref name="fields"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <paramref name="fields"/> is empty. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// <para>The <see cref="ImapClient"/> is not connected.</para> /// <para>-or-</para> /// <para>The <see cref="ImapClient"/> is not authenticated.</para> /// <para>-or-</para> /// <para>The folder is not currently open.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch(int min, int max, MessageSummaryItems items, HashSet<HeaderId> fields, CancellationToken cancellationToken = default (CancellationToken)) { if (min < 0 || min > Count) throw new ArgumentOutOfRangeException ("min"); if (max != -1 && max < min) throw new ArgumentOutOfRangeException ("max"); if (fields == null) throw new ArgumentNullException ("fields"); if (fields.Count == 0) throw new ArgumentException ("The set of header fields cannot be empty.", "fields"); CheckState (true, false); if (min == Count) return new IMessageSummary[0]; var query = FormatSummaryItems (items, fields); var command = string.Format ("FETCH {0} {1}\r\n", GetFetchRange (min, max), query); var ic = new ImapCommand (Engine, cancellationToken, this, command); var results = new SortedDictionary<int, IMessageSummary> (); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = results; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Result != ImapCommandResult.Ok) throw ImapCommandException.Create ("FETCH", ic); return AsReadOnly (results.Values); }
/// <summary> /// Initializes a new instance of the <see cref="T:MailKit.Net.Imap.ImapEvent.MessageNew"/> class. /// </summary> /// <remarks> /// Initializes a new instance of the <see cref="T:MailKit.Net.Imap.ImapEvent.MessageNew"/> class. /// </remarks> /// <param name="items">The message summary items to automatically retrieve for new messages.</param> /// <param name="headers">Additional message headers to retrieve for new messages.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="headers"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// <para>One or more of the specified <paramref name="headers"/> is invalid.</para> /// </exception> public MessageNew(MessageSummaryItems items, IEnumerable <string> headers) : base("MessageNew", true) { request = new FetchRequest(items, headers); }
/// <summary> /// Initializes a new instance of the <see cref="T:MailKit.Net.Imap.ImapEvent.MessageNew"/> class. /// </summary> /// <remarks> /// Initializes a new instance of the <see cref="T:MailKit.Net.Imap.ImapEvent.MessageNew"/> class. /// </remarks> /// <param name="items">The message summary items to automatically retrieve for new messages.</param> public MessageNew(MessageSummaryItems items = MessageSummaryItems.None) : base("MessageNew", true) { request = new FetchRequest(items); }
/// <summary> /// Initializes a new instance of the <see cref="FetchRequest"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="FetchRequest"/>. /// </remarks> /// <param name="items">The items to fetch.</param> /// <param name="headers">The specific set of headers to fetch.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="headers"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// One or more of the specified <paramref name="headers"/> is invalid. /// </exception> public FetchRequest(MessageSummaryItems items, IEnumerable <string> headers) : this(items) { Headers = (headers is HeaderSet set) ? set : new HeaderSet(headers); }
/// <summary> /// Initializes a new instance of the <see cref="FetchRequest"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="FetchRequest"/>. /// </remarks> /// <param name="items">The items to fetch.</param> public FetchRequest(MessageSummaryItems items) { Items = items; }
//---------------------IMAP------MailKit------------------------------- public static async Task <List <MessageParts> > CustomsDownloadBodyPartsAsync(Account element, string FolderName, BinarySearchQuery queryCustom) { List <MessageParts> MessagesListRender = new List <MessageParts>(); List <IMailFolder> myListFolders = new List <IMailFolder>(); using (var client = new ImapClient()) { await client.ConnectAsync(element.IMAPServerDetails, element.IMAPPortDetails, SecureSocketOptions.SslOnConnect); await client.AuthenticateAsync(element.IMAPEmailAddress, element.IMAPEmailBoxPassword); await client.Inbox.OpenAsync(FolderAccess.ReadOnly); var personal = client.GetFolder(client.PersonalNamespaces[0]); IMailFolder CompleteFolder = personal.GetSubfolders()[1]; foreach (var folder in CompleteFolder.GetSubfolders()) { myListFolders.Add(folder); } int indexOfFolder = myListFolders.FindIndex(a => a.Name == FolderName); if (indexOfFolder > 0) { await myListFolders[indexOfFolder].OpenAsync(FolderAccess.ReadOnly); if (queryCustom == null) { DateTime DateNow = new DateTime(); DateNow = DateTime.Now; var query = SearchQuery.DeliveredAfter(new DateTime(2019, 05, 01)).And(SearchQuery.DeliveredBefore(DateNow)); var uids = await myListFolders[indexOfFolder].SearchAsync(query); const MessageSummaryItems SummaryItems = MessageSummaryItems.UniqueId | MessageSummaryItems.Envelope | MessageSummaryItems.Flags | MessageSummaryItems.BodyStructure; var timeout = new CancellationToken(); MessagesList = await myListFolders[indexOfFolder].FetchAsync(uids, SummaryItems, timeout); } if (queryCustom != null) { var uids = myListFolders[indexOfFolder].Search(queryCustom); const MessageSummaryItems SummaryItems = MessageSummaryItems.UniqueId | MessageSummaryItems.Envelope | MessageSummaryItems.Flags | MessageSummaryItems.BodyStructure; var timeout = new CancellationToken(); MessagesList = await myListFolders[indexOfFolder].FetchAsync(uids, SummaryItems, timeout); } foreach (var message in MessagesList) { MessageParts temp = new MessageParts(); temp.Uid = message.UniqueId.ToString(); var bodyPart = message.TextBody; var body = (TextPart)myListFolders[indexOfFolder].GetBodyPart(message.UniqueId, bodyPart); temp.Body = body.Text; string str = message.Envelope.Date.ToString(); int index = str.IndexOf("+") > 0 ? str.IndexOf("+") : str.IndexOf("-"); temp.Date = str.Substring(0, index); temp.From = message.Envelope.From.ToString(); temp.Cc = message.Envelope.Cc.ToString(); temp.Subject = message.Envelope.Subject.ToString(); temp.To = message.Envelope.To.ToString(); MessagesListRender.Add(temp); } } client.Disconnect(true); } return(MessagesListRender); }
public void TestImapClientGMail() { var commands = new List <ImapReplayCommand> (); commands.Add(new ImapReplayCommand("", "gmail.greeting.txt")); commands.Add(new ImapReplayCommand("A00000000 CAPABILITY\r\n", "gmail.capability.txt")); commands.Add(new ImapReplayCommand("A00000001 AUTHENTICATE PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk\r\n", "gmail.authenticate.txt")); commands.Add(new ImapReplayCommand("A00000002 NAMESPACE\r\n", "gmail.namespace.txt")); commands.Add(new ImapReplayCommand("A00000003 LIST \"\" \"INBOX\"\r\n", "gmail.list-inbox.txt")); commands.Add(new ImapReplayCommand("A00000004 XLIST \"\" \"*\"\r\n", "gmail.xlist.txt")); commands.Add(new ImapReplayCommand("A00000005 LIST \"\" \"%\"\r\n", "gmail.list-personal.txt")); commands.Add(new ImapReplayCommand("A00000006 CREATE UnitTests\r\n", "gmail.create-unittests.txt")); commands.Add(new ImapReplayCommand("A00000007 LIST \"\" UnitTests\r\n", "gmail.list-unittests.txt")); commands.Add(new ImapReplayCommand("A00000008 SELECT UnitTests (CONDSTORE)\r\n", "gmail.select-unittests.txt")); for (int i = 0; i < 50; i++) { using (var stream = GetResourceStream(string.Format("common.message.{0}.msg", i))) { var message = MimeMessage.Load(stream); long length = stream.Length; string latin1; stream.Position = 0; using (var reader = new StreamReader(stream, Latin1)) latin1 = reader.ReadToEnd(); var command = string.Format("A{0:D8} APPEND UnitTests (\\Seen) ", i + 9); command += "{" + length + "}\r\n"; commands.Add(new ImapReplayCommand(command, "gmail.go-ahead.txt")); commands.Add(new ImapReplayCommand(latin1 + "\r\n", string.Format("gmail.append.{0}.txt", i + 1))); } } commands.Add(new ImapReplayCommand("A00000059 UID SEARCH RETURN () CHARSET US-ASCII OR TO nsb CC nsb\r\n", "gmail.search.txt")); commands.Add(new ImapReplayCommand("A00000060 UID FETCH 1:3,5,7:9,11:14,26:29,31,34,41:43,50 (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)\r\n", "gmail.search-summary.txt")); commands.Add(new ImapReplayCommand("A00000061 UID FETCH 1 (BODY.PEEK[])\r\n", "gmail.fetch.1.txt")); commands.Add(new ImapReplayCommand("A00000062 UID FETCH 2 (BODY.PEEK[])\r\n", "gmail.fetch.2.txt")); commands.Add(new ImapReplayCommand("A00000063 UID FETCH 3 (BODY.PEEK[])\r\n", "gmail.fetch.3.txt")); commands.Add(new ImapReplayCommand("A00000064 UID FETCH 5 (BODY.PEEK[])\r\n", "gmail.fetch.5.txt")); commands.Add(new ImapReplayCommand("A00000065 UID FETCH 7 (BODY.PEEK[])\r\n", "gmail.fetch.7.txt")); commands.Add(new ImapReplayCommand("A00000066 UID FETCH 8 (BODY.PEEK[])\r\n", "gmail.fetch.8.txt")); commands.Add(new ImapReplayCommand("A00000067 UID FETCH 9 (BODY.PEEK[])\r\n", "gmail.fetch.9.txt")); commands.Add(new ImapReplayCommand("A00000068 UID FETCH 11 (BODY.PEEK[])\r\n", "gmail.fetch.11.txt")); commands.Add(new ImapReplayCommand("A00000069 UID FETCH 12 (BODY.PEEK[])\r\n", "gmail.fetch.12.txt")); commands.Add(new ImapReplayCommand("A00000070 UID FETCH 13 (BODY.PEEK[])\r\n", "gmail.fetch.13.txt")); commands.Add(new ImapReplayCommand("A00000071 UID FETCH 14 (BODY.PEEK[])\r\n", "gmail.fetch.14.txt")); commands.Add(new ImapReplayCommand("A00000072 UID FETCH 26 (BODY.PEEK[])\r\n", "gmail.fetch.26.txt")); commands.Add(new ImapReplayCommand("A00000073 UID FETCH 27 (BODY.PEEK[])\r\n", "gmail.fetch.27.txt")); commands.Add(new ImapReplayCommand("A00000074 UID FETCH 28 (BODY.PEEK[])\r\n", "gmail.fetch.28.txt")); commands.Add(new ImapReplayCommand("A00000075 UID FETCH 29 (BODY.PEEK[])\r\n", "gmail.fetch.29.txt")); commands.Add(new ImapReplayCommand("A00000076 UID FETCH 31 (BODY.PEEK[])\r\n", "gmail.fetch.31.txt")); commands.Add(new ImapReplayCommand("A00000077 UID FETCH 34 (BODY.PEEK[])\r\n", "gmail.fetch.34.txt")); commands.Add(new ImapReplayCommand("A00000078 UID FETCH 41 (BODY.PEEK[])\r\n", "gmail.fetch.41.txt")); commands.Add(new ImapReplayCommand("A00000079 UID FETCH 42 (BODY.PEEK[])\r\n", "gmail.fetch.42.txt")); commands.Add(new ImapReplayCommand("A00000080 UID FETCH 43 (BODY.PEEK[])\r\n", "gmail.fetch.43.txt")); commands.Add(new ImapReplayCommand("A00000081 UID FETCH 50 (BODY.PEEK[])\r\n", "gmail.fetch.50.txt")); commands.Add(new ImapReplayCommand("A00000082 UID STORE 1:3,5,7:9,11:14,26:29,31,34,41:43,50 FLAGS (\\Answered \\Seen)\r\n", "gmail.set-flags.txt")); commands.Add(new ImapReplayCommand("A00000083 UID STORE 1:3,5,7:9,11:14,26:29,31,34,41:43,50 -FLAGS.SILENT (\\Answered)\r\n", "gmail.remove-flags.txt")); commands.Add(new ImapReplayCommand("A00000084 UID STORE 1:3,5,7:9,11:14,26:29,31,34,41:43,50 +FLAGS.SILENT (\\Deleted)\r\n", "gmail.add-flags.txt")); commands.Add(new ImapReplayCommand("A00000085 UNSELECT\r\n", "gmail.unselect-unittests.txt")); commands.Add(new ImapReplayCommand("A00000086 DELETE UnitTests\r\n", "gmail.delete-unittests.txt")); commands.Add(new ImapReplayCommand("A00000087 LOGOUT\r\n", "gmail.logout.txt")); using (var client = new ImapClient()) { try { client.ReplayConnect("localhost", new ImapReplayStream(commands, false), CancellationToken.None); } catch (Exception ex) { Assert.Fail("Did not expect an exception in Connect: {0}", ex); } Assert.IsTrue(client.IsConnected, "Client failed to connect."); Assert.AreEqual(GMailInitialCapabilities, client.Capabilities); Assert.AreEqual(4, client.AuthenticationMechanisms.Count); Assert.IsTrue(client.AuthenticationMechanisms.Contains("XOAUTH"), "Expected SASL XOAUTH auth mechanism"); Assert.IsTrue(client.AuthenticationMechanisms.Contains("XOAUTH2"), "Expected SASL XOAUTH2 auth mechanism"); Assert.IsTrue(client.AuthenticationMechanisms.Contains("PLAIN"), "Expected SASL PLAIN auth mechanism"); Assert.IsTrue(client.AuthenticationMechanisms.Contains("PLAIN-CLIENTTOKEN"), "Expected SASL PLAIN-CLIENTTOKEN auth mechanism"); try { var credentials = new NetworkCredential("username", "password"); // Note: Do not try XOAUTH2 client.AuthenticationMechanisms.Remove("XOAUTH2"); client.Authenticate(credentials, CancellationToken.None); } catch (Exception ex) { Assert.Fail("Did not expect an exception in Authenticate: {0}", ex); } Assert.AreEqual(GMailAuthenticatedCapabilities, client.Capabilities); var inbox = client.Inbox; Assert.IsNotNull(inbox, "Expected non-null Inbox folder."); Assert.AreEqual(FolderAttributes.HasNoChildren, inbox.Attributes, "Expected Inbox attributes to be \\HasNoChildren."); foreach (var special in Enum.GetValues(typeof(SpecialFolder)).OfType <SpecialFolder> ()) { var folder = client.GetFolder(special); if (special != SpecialFolder.Archive) { var expected = GetSpecialFolderAttribute(special) | FolderAttributes.HasNoChildren; Assert.IsNotNull(folder, "Expected non-null {0} folder.", special); Assert.AreEqual(expected, folder.Attributes, "Expected {0} attributes to be \\HasNoChildren.", special); } else { Assert.IsNull(folder, "Expected null {0} folder.", special); } } var personal = client.GetFolder(client.PersonalNamespaces[0]); var folders = personal.GetSubfolders(false, CancellationToken.None).ToList(); Assert.AreEqual(client.Inbox, folders[0], "Expected the first folder to be the Inbox."); Assert.AreEqual("[Gmail]", folders[1].FullName, "Expected the second folder to be [Gmail]."); Assert.AreEqual(FolderAttributes.NoSelect | FolderAttributes.HasChildren, folders[1].Attributes, "Expected [Gmail] folder to be \\Noselect \\HasChildren."); var created = personal.Create("UnitTests", true, CancellationToken.None); Assert.IsNotNull(created.ParentFolder, "The ParentFolder property should not be null."); created.Open(FolderAccess.ReadWrite, CancellationToken.None); for (int i = 0; i < 50; i++) { using (var stream = GetResourceStream(string.Format("common.message.{0}.msg", i))) { var message = MimeMessage.Load(stream); created.Append(message, MessageFlags.Seen, CancellationToken.None); } } var query = SearchQuery.ToContains("nsb").Or(SearchQuery.CcContains("nsb")); var matches = created.Search(query, CancellationToken.None); const MessageSummaryItems items = MessageSummaryItems.Full | MessageSummaryItems.UniqueId; var summaries = created.Fetch(matches, items, CancellationToken.None); foreach (var summary in summaries) { created.GetMessage(summary.UniqueId, CancellationToken.None); } created.SetFlags(matches, MessageFlags.Seen | MessageFlags.Answered, false, CancellationToken.None); created.RemoveFlags(matches, MessageFlags.Answered, true, CancellationToken.None); created.AddFlags(matches, MessageFlags.Deleted, true, CancellationToken.None); created.Close(false, CancellationToken.None); created.Delete(CancellationToken.None); client.Disconnect(true, CancellationToken.None); } }
string FormatSummaryItems (ref MessageSummaryItems items, HashSet<string> fields) { if ((items & MessageSummaryItems.BodyStructure) != 0 && (items & MessageSummaryItems.Body) != 0) { // don't query both the BODY and BODYSTRUCTURE, that's just dumb... items &= ~MessageSummaryItems.Body; } if (!Engine.IsGMail) { // first, eliminate the aliases... if (items == MessageSummaryItems.All) return "ALL"; if (items == MessageSummaryItems.Full) return "FULL"; if (items == MessageSummaryItems.Fast) return "FAST"; } var tokens = new List<string> (); // now add on any additional summary items... if ((items & MessageSummaryItems.UniqueId) != 0) tokens.Add ("UID"); if ((items & MessageSummaryItems.Flags) != 0) tokens.Add ("FLAGS"); if ((items & MessageSummaryItems.InternalDate) != 0) tokens.Add ("INTERNALDATE"); if ((items & MessageSummaryItems.MessageSize) != 0) tokens.Add ("RFC822.SIZE"); if ((items & MessageSummaryItems.Envelope) != 0) tokens.Add ("ENVELOPE"); if ((items & MessageSummaryItems.BodyStructure) != 0) tokens.Add ("BODYSTRUCTURE"); if ((items & MessageSummaryItems.Body) != 0) tokens.Add ("BODY"); if ((Engine.Capabilities & ImapCapabilities.CondStore) != 0) { if ((items & MessageSummaryItems.ModSeq) != 0) tokens.Add ("MODSEQ"); } if ((Engine.Capabilities & ImapCapabilities.GMailExt1) != 0) { // now for the GMail extension items if ((items & MessageSummaryItems.GMailMessageId) != 0) tokens.Add ("X-GM-MSGID"); if ((items & MessageSummaryItems.GMailThreadId) != 0) tokens.Add ("X-GM-THRID"); if ((items & MessageSummaryItems.GMailLabels) != 0) tokens.Add ("X-GM-LABELS"); } if ((items & MessageSummaryItems.References) != 0 || fields != null) { var headers = new StringBuilder ("BODY.PEEK[HEADER.FIELDS ("); bool references = false; if (fields != null) { foreach (var field in fields) { var name = field.ToUpperInvariant (); if (name == "REFERENCES") references = true; headers.Append (name); headers.Append (' '); } } if ((items & MessageSummaryItems.References) != 0 && !references) headers.Append ("REFERENCES "); headers[headers.Length - 1] = ')'; headers.Append (']'); tokens.Add (headers.ToString ()); } if (tokens.Count == 1) return tokens[0]; return string.Format ("({0})", string.Join (" ", tokens)); }
/// <summary> /// Fetches the message summaries for the messages between the two indexes (inclusive) that have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// Fetches the message summaries for the messages between the two indexes (inclusive) that have a higher mod-sequence value than the one specified. /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="items"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// <para>The <see cref="ImapClient"/> is not connected.</para> /// <para>-or-</para> /// <para>The <see cref="ImapClient"/> is not authenticated.</para> /// <para>-or-</para> /// <para>The folder is not currently open.</para> /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="ImapFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch(int min, int max, ulong modseq, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken)) { if (min < 0 || min >= Count) throw new ArgumentOutOfRangeException ("min"); if (max != -1 && max < min) throw new ArgumentOutOfRangeException ("max"); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); if (!SupportsModSeq) throw new NotSupportedException ("The ImapFolder does not support mod-sequences."); CheckState (true, false); var query = FormatSummaryItems (items, null); var command = string.Format ("FETCH {0} {1} (CHANGEDSINCE {2})\r\n", GetFetchRange (min, max), query, modseq); var ic = new ImapCommand (Engine, cancellationToken, this, command); var results = new SortedDictionary<int, IMessageSummary> (); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = results; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Result != ImapCommandResult.Ok) throw ImapCommandException.Create ("FETCH", ic); return AsReadOnly (results.Values); }
/// <summary> /// Fetches the message summaries for the specified message indexes. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message indexes.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the IMAP server may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="indexes">The indexes.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="indexes"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para>One or more of the <paramref name="indexes"/> is invalid.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="ImapClient"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="ImapClient"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The <see cref="ImapFolder"/> is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch (IList<int> indexes, MessageSummaryItems items, HashSet<string> fields, CancellationToken cancellationToken = default (CancellationToken)) { var set = ImapUtils.FormatIndexSet (indexes); if (fields == null) throw new ArgumentNullException ("fields"); if (fields.Count == 0) throw new ArgumentException ("The set of header fields cannot be empty.", "fields"); CheckState (true, false); if (indexes.Count == 0) return new IMessageSummary[0]; var query = FormatSummaryItems (ref items, fields); var command = string.Format ("FETCH {0} {1}\r\n", set, query); var ic = new ImapCommand (Engine, cancellationToken, this, command); var ctx = new FetchSummaryContext (items); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = ctx; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Response != ImapCommandResponse.Ok) throw ImapCommandException.Create ("FETCH", ic); return AsReadOnly (ctx.Results.Values); }
/// <summary> /// Initializes a new instance of the <see cref="T:MailKit.Net.Imap.ImapEvent.MessageNew"/> class. /// </summary> /// <remarks> /// Initializes a new instance of the <see cref="T:MailKit.Net.Imap.ImapEvent.MessageNew"/> class. /// </remarks> /// <param name="items">The message summary items to automatically retrieve for new messages.</param> public MessageNew(MessageSummaryItems items = MessageSummaryItems.None) : base("MessageNew", true) { headers = ImapFolder.EmptyHeaderFields; this.items = items; }
/// <summary> /// Fetches the message summaries for the messages between the two indexes (inclusive) /// that have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the messages between the two /// indexes (inclusive) that have a higher mod-sequence value than the one /// specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the IMAP server may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// </exception> /// <exception cref="System.ArgumentNullException"> /// <paramref name="fields"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <paramref name="fields"/> is empty. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="ImapClient"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="ImapClient"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The <see cref="ImapFolder"/> is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="ImapFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch (int min, int max, ulong modseq, MessageSummaryItems items, HashSet<string> fields, CancellationToken cancellationToken = default (CancellationToken)) { if (min < 0 || min >= Count) throw new ArgumentOutOfRangeException ("min"); if (max != -1 && max < min) throw new ArgumentOutOfRangeException ("max"); if (fields == null) throw new ArgumentNullException ("fields"); if (fields.Count == 0) throw new ArgumentException ("The set of header fields cannot be empty.", "fields"); if (!SupportsModSeq) throw new NotSupportedException ("The ImapFolder does not support mod-sequences."); CheckState (true, false); var query = FormatSummaryItems (ref items, fields); var command = string.Format ("FETCH {0} {1} (CHANGEDSINCE {2})\r\n", GetFetchRange (min, max), query, modseq); var ic = new ImapCommand (Engine, cancellationToken, this, command); var ctx = new FetchSummaryContext (items); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = ctx; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Response != ImapCommandResponse.Ok) throw ImapCommandException.Create ("FETCH", ic); return AsReadOnly (ctx.Results.Values); }
/// <summary> /// Initializes a new instance of the <see cref="T:MailKit.Net.Imap.ImapEvent.MessageNew"/> class. /// </summary> /// <remarks> /// Initializes a new instance of the <see cref="T:MailKit.Net.Imap.ImapEvent.MessageNew"/> class. /// </remarks> /// <param name="items">The message summary items to automatically retrieve for new messages.</param> /// <param name="headers">Additional message headers to retrieve for new messages.</param> public MessageNew(MessageSummaryItems items, HashSet <string> headers) : this(items) { this.headers = ImapUtils.GetUniqueHeaders(headers); }
/// <summary> /// Fetch the message summaries for the specified message UIDs that have a /// higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message UIDs that /// have a higher mod-sequence value than the one specified.</para> /// <para>If the mail store supports quick resynchronization and the application has /// enabled this feature via <see cref="MailStore.EnableQuickResync(CancellationToken)"/>, /// then this method will emit <see cref="MessagesVanished"/> events for messages that /// have vanished since the specified mod-sequence value.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="uids">The UIDs.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="uids"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ArgumentException"> /// One or more of the <paramref name="uids"/> is invalid. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="IMailStore"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public abstract IList<IMessageSummary> Fetch (IList<UniqueId> uids, ulong modseq, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken));
/// <summary> /// Asynchronously fetch the message summaries for the specified message UIDs. /// </summary> /// <remarks> /// <para>Asynchronously fetches the message summaries for the specified message /// UIDs.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="uids">The UIDs.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="uids"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ArgumentException"> /// One or more of the <paramref name="uids"/> is invalid. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public virtual Task<IList<IMessageSummary>> FetchAsync (IList<UniqueId> uids, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken)) { if (uids == null) throw new ArgumentNullException (nameof (uids)); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException (nameof (items)); return Task.Factory.StartNew (() => { lock (SyncRoot) { return Fetch (uids, items, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); }
/// <summary> /// Asynchronously fetch the message summaries for the specified message indexes that /// have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Asynchronously fetches the message summaries for the specified message /// indexes that have a higher mod-sequence value than the one specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="indexes">The indexes.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="indexes"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ArgumentException"> /// One or more of the <paramref name="indexes"/> is invalid. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="MailFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public virtual Task<IList<IMessageSummary>> FetchAsync (IList<int> indexes, ulong modseq, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken)) { if (indexes == null) throw new ArgumentNullException ("indexes"); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); return Task.Factory.StartNew (() => { lock (SyncRoot) { return Fetch (indexes, modseq, items, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); }
/// <summary> /// Asynchronously fetch the message summaries for the specified message UIDs. /// </summary> /// <remarks> /// <para>Asynchronously fetches the message summaries for the specified message /// UIDs.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="uids">The UIDs.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="uids"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para>One or more of the <paramref name="uids"/> is invalid.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public virtual Task<IList<IMessageSummary>> FetchAsync (IList<UniqueId> uids, MessageSummaryItems items, HashSet<string> fields, CancellationToken cancellationToken = default (CancellationToken)) { if (uids == null) throw new ArgumentNullException (nameof (uids)); if (fields == null) throw new ArgumentNullException (nameof (fields)); if (fields.Count == 0) throw new ArgumentException ("The set of header fields cannot be empty.", nameof (fields)); return Task.Factory.StartNew (() => { lock (SyncRoot) { return Fetch (uids, items, fields, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); }
/// <summary> /// Asynchronously fetch the message summaries for the specified message indexes that /// have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Asynchronously fetches the message summaries for the specified message /// indexes that have a higher mod-sequence value than the one specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="indexes">The indexes.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="indexes"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para>One or more of the <paramref name="indexes"/> is invalid.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public virtual Task<IList<IMessageSummary>> FetchAsync (IList<int> indexes, ulong modseq, MessageSummaryItems items, HashSet<HeaderId> fields, CancellationToken cancellationToken = default (CancellationToken)) { if (indexes == null) throw new ArgumentNullException ("indexes"); if (fields == null) throw new ArgumentNullException ("fields"); if (fields.Count == 0) throw new ArgumentException ("The set of header fields cannot be empty.", "fields"); return Task.Factory.StartNew (() => { lock (SyncRoot) { return Fetch (indexes, modseq, items, fields, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); }
public AttachmentProcessorBuilder IncludeMessageHeaders(MessageSummaryItems fetchFlags) { this.fetchFlags = fetchFlags; return(this); }
/// <summary> /// Asynchronously fetch the message summaries for the messages between the two indexes /// (inclusive) that have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Asynchronously fetches the message summaries for the messages between /// the two indexes (inclusive) that have a higher mod-sequence value than the /// one specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="items"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="MailFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public virtual Task<IList<IMessageSummary>> FetchAsync (int min, int max, ulong modseq, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken)) { if (min < 0) throw new ArgumentOutOfRangeException ("min"); if (max != -1 && max < min) throw new ArgumentOutOfRangeException ("max"); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); return Task.Factory.StartNew (() => { lock (SyncRoot) { return Fetch (min, max, modseq, items, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); }
/// <summary> /// Fetches the message summaries for the messages between the two UIDs (inclusive) that have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>If the IMAP server supports the QRESYNC extension and the application has /// enabled this feature via <see cref="ImapClient.EnableQuickResync"/>, then this /// method will emit <see cref="Vanished"/> events for messages that have vanished /// since the specified mod-sequence value.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum UID.</param> /// <param name="max">The maximum UID.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentException"> /// <paramref name="min"/> is invalid. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// <para>The <see cref="ImapClient"/> is not connected.</para> /// <para>-or-</para> /// <para>The <see cref="ImapClient"/> is not authenticated.</para> /// <para>-or-</para> /// <para>The folder is not currently open.</para> /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="ImapFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public IEnumerable<MessageSummary> Fetch(UniqueId min, UniqueId? max, ulong modseq, MessageSummaryItems items, CancellationToken cancellationToken) { if (min.Id == 0) throw new ArgumentException ("The minimum uid is invalid.", "min"); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); if (!SupportsModSeq) throw new NotSupportedException ("The ImapFolder does not support mod-sequences."); CheckState (true, false); var query = FormatSummaryItems (items); var maxValue = max.HasValue ? max.Value.Id.ToString () : "*"; var vanished = Engine.QResyncEnabled ? " VANISHED" : string.Empty; var command = string.Format ("UID FETCH {0}:{1} ({2}) (CHANGEDSINCE {3}{4})\r\n", min.Id, maxValue, query, modseq, vanished); var ic = new ImapCommand (Engine, cancellationToken, this, command); var results = new SortedDictionary<int, MessageSummary> (); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = results; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Result != ImapCommandResult.Ok) throw new ImapCommandException ("FETCH", ic.Result); return results.Values; }
/// <summary> /// Asynchronously fetch the message summaries for the messages between the two indexes /// (inclusive) that have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Asynchronously fetches the message summaries for the messages between /// the two indexes (inclusive) that have a higher mod-sequence value than the /// one specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// </exception> /// <exception cref="System.ArgumentNullException"> /// <paramref name="fields"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <paramref name="fields"/> is empty. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="MailFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public virtual Task<IList<IMessageSummary>> FetchAsync (int min, int max, ulong modseq, MessageSummaryItems items, HashSet<string> fields, CancellationToken cancellationToken = default (CancellationToken)) { if (min < 0) throw new ArgumentOutOfRangeException ("min"); if (max != -1 && max < min) throw new ArgumentOutOfRangeException ("max"); if (fields == null) throw new ArgumentNullException ("fields"); if (fields.Count == 0) throw new ArgumentException ("The set of header fields cannot be empty.", "fields"); return Task.Factory.StartNew (() => { lock (SyncRoot) { return Fetch (min, max, modseq, items, fields, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); }
/// <summary> /// Fetches the message summaries for the specified message UIDs. /// </summary> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="uids">The UIDs.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="uids"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ArgumentException"> /// One or more of the <paramref name="uids"/> is invalid. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// <para>The <see cref="ImapClient"/> is not connected.</para> /// <para>-or-</para> /// <para>The <see cref="ImapClient"/> is not authenticated.</para> /// <para>-or-</para> /// <para>The folder is not currently open.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public IEnumerable<MessageSummary> Fetch(UniqueId[] uids, MessageSummaryItems items, CancellationToken cancellationToken) { var query = FormatSummaryItems (items); var set = ImapUtils.FormatUidSet (uids); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); CheckState (true, false); if (uids.Length == 0) return new MessageSummary[0]; var command = string.Format ("UID FETCH {0} ({1})\r\n", set, query); var ic = Engine.QueueCommand (cancellationToken, this, command); var results = new SortedDictionary<int, MessageSummary> (); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = results; Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Result != ImapCommandResult.Ok) throw new ImapCommandException ("FETCH", ic.Result); return results.Values; }
public FetchSummaryContext (MessageSummaryItems requestedItems) { Results = new SortedDictionary<int, IMessageSummary> (); RequestedItems = requestedItems; }
/// <summary> /// Fetches the message summaries for the messages between the two UIDs, inclusive. /// </summary> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum UID.</param> /// <param name="max">The maximum UID, or <c>null</c> to specify no upper bound.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentException"> /// <paramref name="min"/> is invalid. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// <para>The <see cref="ImapClient"/> is not connected.</para> /// <para>-or-</para> /// <para>The <see cref="ImapClient"/> is not authenticated.</para> /// <para>-or-</para> /// <para>The folder is not currently open.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public IEnumerable<MessageSummary> Fetch(UniqueId min, UniqueId? max, MessageSummaryItems items, CancellationToken cancellationToken) { if (min.Id == 0) throw new ArgumentException ("The minimum uid is invalid.", "min"); var query = FormatSummaryItems (items); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); CheckState (true, false); var maxValue = max.HasValue ? max.Value.Id.ToString () : "*"; var command = string.Format ("UID FETCH {0}:{1} ({2})\r\n", min.Id, maxValue, query); var ic = Engine.QueueCommand (cancellationToken, this, command); var results = new SortedDictionary<int, MessageSummary> (); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = results; Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Result != ImapCommandResult.Ok) throw new ImapCommandException ("FETCH", ic.Result); return results.Values; }
/// <summary> /// Fetches the message summaries for the specified message UIDs. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message UIDs.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the IMAP server may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="uids">The UIDs.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="uids"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ArgumentException"> /// One or more of the <paramref name="uids"/> is invalid. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="FolderNotOpenException"> /// The <see cref="ImapFolder"/> is not currently open. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="ImapClient"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="ImapClient"/> is not authenticated. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch (IList<UniqueId> uids, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken)) { var set = ImapUtils.FormatUidSet (uids); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); CheckState (true, false); if (uids.Count == 0) return new IMessageSummary[0]; var query = FormatSummaryItems (ref items, null); var command = string.Format ("UID FETCH {0} {1}\r\n", set, query); var ic = new ImapCommand (Engine, cancellationToken, this, command); var ctx = new FetchSummaryContext (items); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = ctx; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Response != ImapCommandResponse.Ok) throw ImapCommandException.Create ("FETCH", ic); return AsReadOnly (ctx.Results.Values); }
/// <summary> /// Fetches the message summaries for the specified message indexes that have a higher mod-sequence value than the one specified. /// </summary> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="indexes">The indexes.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="indexes"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ArgumentException"> /// One or more of the <paramref name="indexes"/> is invalid. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// <para>The <see cref="ImapClient"/> is not connected.</para> /// <para>-or-</para> /// <para>The <see cref="ImapClient"/> is not authenticated.</para> /// <para>-or-</para> /// <para>The folder is not currently open.</para> /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="ImapFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public IEnumerable<MessageSummary> Fetch(int[] indexes, ulong modseq, MessageSummaryItems items, CancellationToken cancellationToken) { var set = ImapUtils.FormatIndexSet (indexes); var query = FormatSummaryItems (items); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); if (!SupportsModSeq) throw new NotSupportedException ("The ImapFolder does not support mod-sequences."); CheckState (true, false); if (indexes.Length == 0) return new MessageSummary[0]; var command = string.Format ("FETCH {0} ({1}) (CHANGEDSINCE {2})\r\n", set, query, modseq); var ic = Engine.QueueCommand (cancellationToken, this, command); var results = new SortedDictionary<int, MessageSummary> (); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = results; Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Result != ImapCommandResult.Ok) throw new ImapCommandException ("FETCH", ic.Result); return results.Values; }
/// <summary> /// Fetches the message summaries for the specified message indexes. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message indexes.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the IMAP server may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="indexes">The indexes.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="indexes"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para>One or more of the <paramref name="indexes"/> is invalid.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="ImapClient"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="ImapClient"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The <see cref="ImapFolder"/> is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch (IList<int> indexes, MessageSummaryItems items, HashSet<HeaderId> fields, CancellationToken cancellationToken = default (CancellationToken)) { return Fetch (indexes, items, GetHeaderNames (fields), cancellationToken); }
/// <summary> /// Fetches the message summaries for the messages between the two indexes (inclusive) that have a higher mod-sequence value than the one specified. /// </summary> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="items"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// <para>The <see cref="ImapClient"/> is not connected.</para> /// <para>-or-</para> /// <para>The <see cref="ImapClient"/> is not authenticated.</para> /// <para>-or-</para> /// <para>The folder is not currently open.</para> /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="ImapFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public IEnumerable<MessageSummary> Fetch(int min, int max, ulong modseq, MessageSummaryItems items, CancellationToken cancellationToken) { if (min < 0 || min >= Count) throw new ArgumentOutOfRangeException ("min"); if ((max != -1 && max < min) || max >= Count) throw new ArgumentOutOfRangeException ("max"); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); if (!SupportsModSeq) throw new NotSupportedException ("The ImapFolder does not support mod-sequences."); CheckState (true, false); var query = FormatSummaryItems (items); var maxValue = max != -1 ? (max + 1).ToString () : "*"; var command = string.Format ("FETCH {0}:{1} ({2}) (CHANGEDSINCE {3})\r\n", min + 1, maxValue, query, modseq); var ic = Engine.QueueCommand (cancellationToken, this, command); var results = new SortedDictionary<int, MessageSummary> (); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = results; Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Result != ImapCommandResult.Ok) throw new ImapCommandException ("FETCH", ic.Result); return results.Values; }
/// <summary> /// Fetches the message summaries for the specified message indexes that have a /// higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message indexes that /// have a higher mod-sequence value than the one specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the IMAP server may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="indexes">The indexes.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="indexes"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="items"/> is empty. /// </exception> /// <exception cref="System.ArgumentException"> /// One or more of the <paramref name="indexes"/> is invalid. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="ImapClient"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="ImapClient"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The <see cref="ImapFolder"/> is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="ImapFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch (IList<int> indexes, ulong modseq, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken)) { var set = ImapUtils.FormatIndexSet (indexes); if (items == MessageSummaryItems.None) throw new ArgumentOutOfRangeException ("items"); if (!SupportsModSeq) throw new NotSupportedException ("The ImapFolder does not support mod-sequences."); CheckState (true, false); if (indexes.Count == 0) return new IMessageSummary[0]; var query = FormatSummaryItems (ref items, null); var command = string.Format ("FETCH {0} {1} (CHANGEDSINCE {2})\r\n", set, query, modseq); var ic = new ImapCommand (Engine, cancellationToken, this, command); var ctx = new FetchSummaryContext (items); ic.RegisterUntaggedHandler ("FETCH", FetchSummaryItems); ic.UserData = ctx; Engine.QueueCommand (ic); Engine.Wait (ic); ProcessResponseCodes (ic, null); if (ic.Response != ImapCommandResponse.Ok) throw ImapCommandException.Create ("FETCH", ic); return AsReadOnly (ctx.Results.Values); }
string FormatSummaryItems(MessageSummaryItems items) { string query; if ((items & MessageSummaryItems.BodyStructure) != 0 && (items & MessageSummaryItems.Body) != 0) { // don't query both the BODY and BODYSTRUCTURE, that's just dumb... items &= ~MessageSummaryItems.Body; } // Note: GMail doesn't properly handle aliases (or at least it doesn't handle "FULL")... if ((Engine.Capabilities & ImapCapabilities.GMailExt1) == 0) { // first, eliminate the aliases... if ((items & MessageSummaryItems.Full) == MessageSummaryItems.Full) { items &= ~MessageSummaryItems.Full; query = "FULL "; } else if ((items & MessageSummaryItems.All) == MessageSummaryItems.All) { items &= ~MessageSummaryItems.All; query = "ALL "; } else if ((items & MessageSummaryItems.Fast) == MessageSummaryItems.Fast) { items &= ~MessageSummaryItems.Fast; query = "FAST "; } else { query = string.Empty; } } else { query = string.Empty; } // now add on any additional summary items... if ((items & MessageSummaryItems.Uid) != 0) query += "UID "; if ((items & MessageSummaryItems.Flags) != 0) query += "FLAGS "; if ((items & MessageSummaryItems.InternalDate) != 0) query += "INTERNALDATE "; if ((items & MessageSummaryItems.MessageSize) != 0) query += "RFC822.SIZE "; if ((items & MessageSummaryItems.Envelope) != 0) query += "ENVELOPE "; if ((items & MessageSummaryItems.BodyStructure) != 0) query += "BODYSTRUCTURE "; if ((items & MessageSummaryItems.Body) != 0) query += "BODY "; if ((Engine.Capabilities & ImapCapabilities.CondStore) != 0) { if ((items & MessageSummaryItems.ModSeq) != 0) query += "MODSEQ "; } if ((Engine.Capabilities & ImapCapabilities.GMailExt1) != 0) { // now for the GMail extension items if ((items & MessageSummaryItems.GMailMessageId) != 0) query += "X-GM-MSGID "; if ((items & MessageSummaryItems.GMailThreadId) != 0) query += "X-GM-THRID "; } return query.TrimEnd (); }
/// <summary> /// Fetches the message summaries for the messages between the two indexes (inclusive) /// that have a higher mod-sequence value than the one specified. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the messages between the two /// indexes (inclusive) that have a higher mod-sequence value than the one /// specified.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the IMAP server may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="min">The minimum index.</param> /// <param name="max">The maximum index, or <c>-1</c> to specify no upper bound.</param> /// <param name="modseq">The mod-sequence value.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="min"/> is out of range.</para> /// <para>-or-</para> /// <para><paramref name="max"/> is out of range.</para> /// </exception> /// <exception cref="System.ArgumentNullException"> /// <paramref name="fields"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <paramref name="fields"/> is empty. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="ImapClient"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="ImapClient"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="ImapClient"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The <see cref="ImapFolder"/> is not currently open. /// </exception> /// <exception cref="System.NotSupportedException"> /// The <see cref="ImapFolder"/> does not support mod-sequences. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ImapProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="ImapCommandException"> /// The server replied with a NO or BAD response. /// </exception> public override IList<IMessageSummary> Fetch (int min, int max, ulong modseq, MessageSummaryItems items, HashSet<HeaderId> fields, CancellationToken cancellationToken = default (CancellationToken)) { return Fetch (min, max, modseq, items, GetHeaderNames (fields), cancellationToken); }
/// <summary> /// Fetch the message summaries for the specified message UIDs. /// </summary> /// <remarks> /// <para>Fetches the message summaries for the specified message UIDs.</para> /// <para>It should be noted that if another client has modified any message /// in the folder, the mail service may choose to return information that was /// not explicitly requested. It is therefore important to be prepared to /// handle both additional fields on a <see cref="IMessageSummary"/> for /// messages that were requested as well as summaries for messages that were /// not requested at all.</para> /// </remarks> /// <returns>An enumeration of summaries for the requested messages.</returns> /// <param name="uids">The UIDs.</param> /// <param name="items">The message summary items to fetch.</param> /// <param name="fields">The desired header fields.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="uids"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para>One or more of the <paramref name="uids"/> is invalid.</para> /// <para>-or-</para> /// <para><paramref name="fields"/> is empty.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="FolderNotOpenException"> /// The folder is not currently open. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public abstract IList<IMessageSummary> Fetch (IList<UniqueId> uids, MessageSummaryItems items, HashSet<HeaderId> fields, CancellationToken cancellationToken = default (CancellationToken));
public async void TestImapClientGMail() { var commands = new List <ImapReplayCommand> (); commands.Add(new ImapReplayCommand("", "gmail.greeting.txt")); commands.Add(new ImapReplayCommand("A00000000 CAPABILITY\r\n", "gmail.capability.txt")); commands.Add(new ImapReplayCommand("A00000001 AUTHENTICATE PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk\r\n", "gmail.authenticate.txt")); commands.Add(new ImapReplayCommand("A00000002 NAMESPACE\r\n", "gmail.namespace.txt")); commands.Add(new ImapReplayCommand("A00000003 LIST \"\" \"INBOX\"\r\n", "gmail.list-inbox.txt")); commands.Add(new ImapReplayCommand("A00000004 XLIST \"\" \"*\"\r\n", "gmail.xlist.txt")); commands.Add(new ImapReplayCommand("A00000005 LIST \"\" \"%\"\r\n", "gmail.list-personal.txt")); commands.Add(new ImapReplayCommand("A00000006 CREATE UnitTests\r\n", ImapReplayCommandResponse.OK)); commands.Add(new ImapReplayCommand("A00000007 LIST \"\" UnitTests\r\n", "gmail.list-unittests.txt")); commands.Add(new ImapReplayCommand("A00000008 SELECT UnitTests (CONDSTORE)\r\n", "gmail.select-unittests.txt")); for (int i = 0; i < 50; i++) { MimeMessage message; string latin1; long length; using (var resource = GetResourceStream(string.Format("common.message.{0}.msg", i))) message = MimeMessage.Load(resource); using (var stream = new MemoryStream()) { var options = FormatOptions.Default.Clone(); options.NewLineFormat = NewLineFormat.Dos; message.WriteTo(options, stream); length = stream.Length; stream.Position = 0; using (var reader = new StreamReader(stream, Latin1)) latin1 = reader.ReadToEnd(); } var command = string.Format("A{0:D8} APPEND UnitTests (\\Seen) ", i + 9); command += "{" + length + "}\r\n"; commands.Add(new ImapReplayCommand(command, "gmail.go-ahead.txt")); commands.Add(new ImapReplayCommand(latin1 + "\r\n", string.Format("gmail.append.{0}.txt", i + 1))); } commands.Add(new ImapReplayCommand("A00000059 UID SEARCH RETURN () OR TO nsb CC nsb\r\n", "gmail.search.txt")); commands.Add(new ImapReplayCommand("A00000060 UID FETCH 1:3,5,7:9,11:14,26:29,31,34,41:43,50 (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)\r\n", "gmail.search-summary.txt")); commands.Add(new ImapReplayCommand("A00000061 UID FETCH 1 (BODY.PEEK[])\r\n", "gmail.fetch.1.txt")); commands.Add(new ImapReplayCommand("A00000062 UID FETCH 2 (BODY.PEEK[])\r\n", "gmail.fetch.2.txt")); commands.Add(new ImapReplayCommand("A00000063 UID FETCH 3 (BODY.PEEK[])\r\n", "gmail.fetch.3.txt")); commands.Add(new ImapReplayCommand("A00000064 UID FETCH 5 (BODY.PEEK[])\r\n", "gmail.fetch.5.txt")); commands.Add(new ImapReplayCommand("A00000065 UID FETCH 7 (BODY.PEEK[])\r\n", "gmail.fetch.7.txt")); commands.Add(new ImapReplayCommand("A00000066 UID FETCH 8 (BODY.PEEK[])\r\n", "gmail.fetch.8.txt")); commands.Add(new ImapReplayCommand("A00000067 UID FETCH 9 (BODY.PEEK[])\r\n", "gmail.fetch.9.txt")); commands.Add(new ImapReplayCommand("A00000068 UID FETCH 11 (BODY.PEEK[])\r\n", "gmail.fetch.11.txt")); commands.Add(new ImapReplayCommand("A00000069 UID FETCH 12 (BODY.PEEK[])\r\n", "gmail.fetch.12.txt")); commands.Add(new ImapReplayCommand("A00000070 UID FETCH 13 (BODY.PEEK[])\r\n", "gmail.fetch.13.txt")); commands.Add(new ImapReplayCommand("A00000071 UID FETCH 14 (BODY.PEEK[])\r\n", "gmail.fetch.14.txt")); commands.Add(new ImapReplayCommand("A00000072 UID FETCH 26 (BODY.PEEK[])\r\n", "gmail.fetch.26.txt")); commands.Add(new ImapReplayCommand("A00000073 UID FETCH 27 (BODY.PEEK[])\r\n", "gmail.fetch.27.txt")); commands.Add(new ImapReplayCommand("A00000074 UID FETCH 28 (BODY.PEEK[])\r\n", "gmail.fetch.28.txt")); commands.Add(new ImapReplayCommand("A00000075 UID FETCH 29 (BODY.PEEK[])\r\n", "gmail.fetch.29.txt")); commands.Add(new ImapReplayCommand("A00000076 UID FETCH 31 (BODY.PEEK[])\r\n", "gmail.fetch.31.txt")); commands.Add(new ImapReplayCommand("A00000077 UID FETCH 34 (BODY.PEEK[])\r\n", "gmail.fetch.34.txt")); commands.Add(new ImapReplayCommand("A00000078 UID FETCH 41 (BODY.PEEK[])\r\n", "gmail.fetch.41.txt")); commands.Add(new ImapReplayCommand("A00000079 UID FETCH 42 (BODY.PEEK[])\r\n", "gmail.fetch.42.txt")); commands.Add(new ImapReplayCommand("A00000080 UID FETCH 43 (BODY.PEEK[])\r\n", "gmail.fetch.43.txt")); commands.Add(new ImapReplayCommand("A00000081 UID FETCH 50 (BODY.PEEK[])\r\n", "gmail.fetch.50.txt")); commands.Add(new ImapReplayCommand("A00000082 UID STORE 1:3,5,7:9,11:14,26:29,31,34,41:43,50 FLAGS (\\Answered \\Seen)\r\n", "gmail.set-flags.txt")); commands.Add(new ImapReplayCommand("A00000083 UID STORE 1:3,5,7:9,11:14,26:29,31,34,41:43,50 -FLAGS.SILENT (\\Answered)\r\n", ImapReplayCommandResponse.OK)); commands.Add(new ImapReplayCommand("A00000084 UID STORE 1:3,5,7:9,11:14,26:29,31,34,41:43,50 +FLAGS.SILENT (\\Deleted)\r\n", "gmail.add-flags.txt")); commands.Add(new ImapReplayCommand("A00000085 UNSELECT\r\n", ImapReplayCommandResponse.OK)); commands.Add(new ImapReplayCommand("A00000086 SUBSCRIBE UnitTests\r\n", ImapReplayCommandResponse.OK)); commands.Add(new ImapReplayCommand("A00000087 LSUB \"\" \"%\"\r\n", "gmail.lsub-personal.txt")); commands.Add(new ImapReplayCommand("A00000088 UNSUBSCRIBE UnitTests\r\n", ImapReplayCommandResponse.OK)); commands.Add(new ImapReplayCommand("A00000089 CREATE UnitTests/Dummy\r\n", ImapReplayCommandResponse.OK)); commands.Add(new ImapReplayCommand("A00000090 LIST \"\" UnitTests/Dummy\r\n", "gmail.list-unittests-dummy.txt")); commands.Add(new ImapReplayCommand("A00000091 RENAME UnitTests RenamedUnitTests\r\n", ImapReplayCommandResponse.OK)); commands.Add(new ImapReplayCommand("A00000092 DELETE RenamedUnitTests\r\n", ImapReplayCommandResponse.OK)); commands.Add(new ImapReplayCommand("A00000093 LOGOUT\r\n", "gmail.logout.txt")); using (var client = new ImapClient()) { try { client.ReplayConnect("localhost", new ImapReplayStream(commands, false)); } catch (Exception ex) { Assert.Fail("Did not expect an exception in Connect: {0}", ex); } Assert.IsTrue(client.IsConnected, "Client failed to connect."); Assert.AreEqual(GMailInitialCapabilities, client.Capabilities); Assert.AreEqual(4, client.AuthenticationMechanisms.Count); Assert.IsTrue(client.AuthenticationMechanisms.Contains("XOAUTH"), "Expected SASL XOAUTH auth mechanism"); Assert.IsTrue(client.AuthenticationMechanisms.Contains("XOAUTH2"), "Expected SASL XOAUTH2 auth mechanism"); Assert.IsTrue(client.AuthenticationMechanisms.Contains("PLAIN"), "Expected SASL PLAIN auth mechanism"); Assert.IsTrue(client.AuthenticationMechanisms.Contains("PLAIN-CLIENTTOKEN"), "Expected SASL PLAIN-CLIENTTOKEN auth mechanism"); // Note: Do not try XOAUTH2 client.AuthenticationMechanisms.Remove("XOAUTH2"); try { await client.AuthenticateAsync("username", "password"); } catch (Exception ex) { Assert.Fail("Did not expect an exception in Authenticate: {0}", ex); } Assert.AreEqual(GMailAuthenticatedCapabilities, client.Capabilities); var inbox = client.Inbox; Assert.IsNotNull(inbox, "Expected non-null Inbox folder."); Assert.AreEqual(FolderAttributes.Inbox | FolderAttributes.HasNoChildren, inbox.Attributes, "Expected Inbox attributes to be \\HasNoChildren."); foreach (var special in Enum.GetValues(typeof(SpecialFolder)).OfType <SpecialFolder> ()) { var folder = client.GetFolder(special); if (special != SpecialFolder.Archive) { var expected = GetSpecialFolderAttribute(special) | FolderAttributes.HasNoChildren; Assert.IsNotNull(folder, "Expected non-null {0} folder.", special); Assert.AreEqual(expected, folder.Attributes, "Expected {0} attributes to be \\HasNoChildren.", special); } else { Assert.IsNull(folder, "Expected null {0} folder.", special); } } // disable LIST-EXTENDED client.Capabilities &= ~ImapCapabilities.ListExtended; var personal = client.GetFolder(client.PersonalNamespaces[0]); var folders = (await personal.GetSubfoldersAsync()).ToList(); Assert.AreEqual(client.Inbox, folders[0], "Expected the first folder to be the Inbox."); Assert.AreEqual("[Gmail]", folders[1].FullName, "Expected the second folder to be [Gmail]."); Assert.AreEqual(FolderAttributes.NoSelect | FolderAttributes.HasChildren, folders[1].Attributes, "Expected [Gmail] folder to be \\Noselect \\HasChildren."); var created = await personal.CreateAsync("UnitTests", true); Assert.IsNotNull(created, "Expected a non-null created folder."); Assert.AreEqual(FolderAttributes.HasNoChildren, created.Attributes); Assert.IsNotNull(created.ParentFolder, "The ParentFolder property should not be null."); const MessageFlags ExpectedPermanentFlags = MessageFlags.Answered | MessageFlags.Flagged | MessageFlags.Draft | MessageFlags.Deleted | MessageFlags.Seen | MessageFlags.UserDefined; const MessageFlags ExpectedAcceptedFlags = MessageFlags.Answered | MessageFlags.Flagged | MessageFlags.Draft | MessageFlags.Deleted | MessageFlags.Seen; var access = await created.OpenAsync(FolderAccess.ReadWrite); Assert.AreEqual(FolderAccess.ReadWrite, access, "The UnitTests folder was not opened with the expected access mode."); Assert.AreEqual(ExpectedPermanentFlags, created.PermanentFlags, "The PermanentFlags do not match the expected value."); Assert.AreEqual(ExpectedAcceptedFlags, created.AcceptedFlags, "The AcceptedFlags do not match the expected value."); for (int i = 0; i < 50; i++) { using (var stream = GetResourceStream(string.Format("common.message.{0}.msg", i))) { var message = MimeMessage.Load(stream); var uid = await created.AppendAsync(message, MessageFlags.Seen); Assert.IsTrue(uid.HasValue, "Expected a UID to be returned from folder.Append()."); Assert.AreEqual((uint)(i + 1), uid.Value.Id, "The UID returned from the APPEND command does not match the expected UID."); } } var query = SearchQuery.ToContains("nsb").Or(SearchQuery.CcContains("nsb")); var matches = await created.SearchAsync(query); const MessageSummaryItems items = MessageSummaryItems.Full | MessageSummaryItems.UniqueId; var summaries = await created.FetchAsync(matches, items); foreach (var summary in summaries) { if (summary.UniqueId.IsValid) { await created.GetMessageAsync(summary.UniqueId); } else { await created.GetMessageAsync(summary.Index); } } await created.SetFlagsAsync(matches, MessageFlags.Seen | MessageFlags.Answered, false); await created.RemoveFlagsAsync(matches, MessageFlags.Answered, true); await created.AddFlagsAsync(matches, MessageFlags.Deleted, true); await created.CloseAsync(); Assert.IsFalse(created.IsOpen, "Expected the UnitTests folder to be closed."); await created.SubscribeAsync(); Assert.IsTrue(created.IsSubscribed, "Expected IsSubscribed to be true after subscribing to the folder."); var subscribed = (await personal.GetSubfoldersAsync(true)).ToList(); Assert.IsTrue(subscribed.Contains(created), "Expected the list of subscribed folders to contain the UnitTests folder."); await created.UnsubscribeAsync(); Assert.IsFalse(created.IsSubscribed, "Expected IsSubscribed to be false after unsubscribing from the folder."); var dummy = await created.CreateAsync("Dummy", true); bool dummyRenamed = false; bool renamed = false; bool deleted = false; dummy.Renamed += (sender, e) => { dummyRenamed = true; }; created.Renamed += (sender, e) => { renamed = true; }; await created.RenameAsync(created.ParentFolder, "RenamedUnitTests"); Assert.AreEqual("RenamedUnitTests", created.Name); Assert.AreEqual("RenamedUnitTests", created.FullName); Assert.IsTrue(renamed, "Expected the Rename event to be emitted for the UnitTests folder."); Assert.AreEqual("RenamedUnitTests/Dummy", dummy.FullName); Assert.IsTrue(dummyRenamed, "Expected the Rename event to be emitted for the UnitTests/Dummy folder."); created.Deleted += (sender, e) => { deleted = true; }; await created.DeleteAsync(); Assert.IsTrue(deleted, "Expected the Deleted event to be emitted for the UnitTests folder."); await client.DisconnectAsync(true); } }
public MessageNew(MessageSummaryItems messageSummaryItems = MessageSummaryItems.None, HashSet <string> fields = null) : base("MessageNew", true) { MessageSummaryItems = messageSummaryItems; Headers = fields; }