Exemple #1
0
        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;
 }
Exemple #3
0
		/// <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));
Exemple #4
0
		/// <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));
Exemple #5
0
		/// <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));
Exemple #6
0
		/// <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));
Exemple #7
0
 public MessageNew(MessageSummaryItems messageSummaryItems, HashSet <HeaderId> fields) : base("MessageNew", true)
 {
     MessageSummaryItems = messageSummaryItems;
     Headers             = ImapFolder.GetHeaderNames(fields);
 }
Exemple #8
0
		/// <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);
		}
Exemple #9
0
		/// <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);
		}
Exemple #10
0
        /// <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);
        }
Exemple #11
0
 /// <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);
 }
Exemple #12
0
 /// <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);
 }
Exemple #13
0
 /// <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);
 }
Exemple #14
0
 /// <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;
 }
Exemple #15
0
        //---------------------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);
        }
Exemple #16
0
        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);
            }
        }
Exemple #17
0
		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));
		}
Exemple #18
0
        /// <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);
        }
Exemple #19
0
		/// <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);
		}
Exemple #20
0
 /// <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;
 }
Exemple #21
0
		/// <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);
		}
Exemple #22
0
 /// <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);
 }
Exemple #23
0
		/// <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));
Exemple #24
0
		/// <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);
		}
Exemple #25
0
		/// <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);
		}
Exemple #26
0
		/// <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);
		}
Exemple #27
0
		/// <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);
 }
Exemple #29
0
		/// <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);
		}
Exemple #30
0
        /// <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;
        }
Exemple #31
0
		/// <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);
		}
Exemple #32
0
        /// <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;
        }
Exemple #33
0
			public FetchSummaryContext (MessageSummaryItems requestedItems)
			{
				Results = new SortedDictionary<int, IMessageSummary> ();
				RequestedItems = requestedItems;
			}
Exemple #34
0
        /// <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;
        }
Exemple #35
0
		/// <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);
		}
Exemple #36
0
        /// <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;
        }
Exemple #37
0
		/// <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);
		}
Exemple #38
0
        /// <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;
        }
Exemple #39
0
		/// <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);
		}
Exemple #40
0
        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 ();
        }
Exemple #41
0
		/// <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);
		}
Exemple #42
0
		/// <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);
            }
        }
Exemple #44
0
 public MessageNew(MessageSummaryItems messageSummaryItems = MessageSummaryItems.None, HashSet <string> fields = null) : base("MessageNew", true)
 {
     MessageSummaryItems = messageSummaryItems;
     Headers             = fields;
 }