public IEnumerable<uint> Search(SearchCondition criteria, string mailbox = null) { return _internalClient.Search(criteria, mailbox); }
/// <summary> /// Searches the specified mailbox for messages that match the given /// searching criteria. /// </summary> /// <param name="criteria">A search criteria expression. Only messages /// that match this expression will be included in the result set returned /// by this method.</param> /// <param name="mailbox">The mailbox that will be searched. If this parameter is /// omitted, the value of the DefaultMailbox property is used to determine the mailbox /// to operate on.</param> /// <exception cref="NotAuthenticatedException">Thrown if the method was called /// in a non-authenticated state, i.e. before logging into the server with /// valid credentials.</exception> /// <exception cref="BadServerResponseException">Thrown if the search could /// not be completed. The message property of the exception contains the error /// message returned by the server.</exception> /// <exception cref="NotSupportedException">Thrown if the search values /// contain characters beyond the ASCII range and the server does not support /// handling such strings.</exception> /// <returns>An array of unique identifier (UID) message attributes which /// can be used with the GetMessage family of methods to download mail /// messages.</returns> /// <remarks>A unique identifier (UID) is a 32-bit value assigned to each /// message which uniquely identifies the message within a mailbox. No two /// messages in a mailbox share the the same UID.</remarks> /// <include file='Examples.xml' path='S22/Imap/ImapClient[@name="Search"]/*'/> public uint[] Search(SearchCondition criteria, string mailbox = null) { if (!Authed) throw new NotAuthenticatedException(); lock (sequenceLock) { PauseIdling(); SelectMailbox(mailbox); string tag = GetTag(), str = criteria.ToString(); StringReader reader = new StringReader(str); bool useUTF8 = str.Contains("\r\n"); string line = reader.ReadLine(); string response = SendCommandGetResponse(tag + "UID SEARCH " + (useUTF8 ? "CHARSET UTF-8 " : "") + line); // If our search string consists of multiple lines, we're sending some // strings in literal form and need to issue continuation requests. while ((line = reader.ReadLine()) != null) { if (!response.StartsWith("+")) { ResumeIdling(); throw new NotSupportedException("Please restrict your search " + "to ASCII-only characters", new BadServerResponseException(response)); } response = SendCommandGetResponse(line); } List<uint> result = new List<uint>(); while (response.StartsWith("*")) { Match m = Regex.Match(response, @"^\* SEARCH (.+)"); if (m.Success) { string[] v = m.Groups[1].Value.Trim().Split(' '); foreach (string s in v) { try { result.Add(Convert.ToUInt32(s)); } catch(FormatException) { } } } response = GetResponse(); } ResumeIdling(); if (!IsResponseOK(response, tag)) throw new BadServerResponseException(response); return result.ToArray(); } }
/// <summary> /// Creates a <see cref="SearchCondition"/> object from a <see cref="EmailSearchCriteria"/> /// </summary> /// <param name="searchCriteria"></param> /// <returns></returns> private SearchCondition GetSearchCondition(EmailSearchCriteria searchCriteria) { var searchCondition = new SearchCondition(); if (!string.IsNullOrWhiteSpace(searchCriteria.From)) searchCondition = searchCondition.And(SearchCondition.From(searchCriteria.From)); if (searchCriteria.After.HasValue) searchCondition = searchCondition.And(SearchCondition.SentBefore(searchCriteria.After.Value)); if (searchCriteria.Since.HasValue) searchCondition = searchCondition.And(SearchCondition.SentSince(searchCriteria.Since.Value)); if (searchCriteria.Unread.HasValue) searchCondition = searchCondition.And(searchCriteria.Unread.Value ? SearchCondition.Unseen() : SearchCondition.Seen()); if (searchCriteria.SubjectKeywords != null && searchCriteria.SubjectKeywords.Any()) searchCondition = searchCondition.And( searchCriteria.SubjectKeywords.Select(SearchCondition.Subject).Aggregate((sc1, sc2) => sc1.Or(sc2))); if (searchCriteria.BodyKeywords != null && searchCriteria.BodyKeywords.Any()) searchCondition = searchCondition.And( searchCriteria.BodyKeywords.Select(SearchCondition.Body).Aggregate((sc1, sc2) => sc1.Or(sc2))); return searchCondition; }
/// <summary> /// Searches the specified mailbox for messages that match the given /// searching criteria. /// </summary> /// <param name="criteria">A search criteria expression. Only messages /// that match this expression will be included in the result set returned /// by this method.</param> /// <param name="mailbox">The mailbox that will be searched. If this parameter is /// omitted, the value of the DefaultMailbox property is used to determine the mailbox /// to operate on.</param> /// <exception cref="NotAuthenticatedException">Thrown if the method was called /// in a non-authenticated state, i.e. before logging into the server with /// valid credentials.</exception> /// <exception cref="BadServerResponseException">Thrown if the search could /// not be completed. The message property of the exception contains the error /// message returned by the server.</exception> /// <returns>An array of unique identifier (UID) message attributes which /// can be used with the GetMessage family of methods to download mail /// messages.</returns> /// <remarks>A unique identifier (UID) is a 32-bit value assigned to each /// message which uniquely identifies the message within a mailbox. No two /// messages in a mailbox share the the same UID.</remarks> /// <include file='Examples.xml' path='S22/Imap/ImapClient[@name="Search"]/*'/> public uint[] Search(SearchCondition criteria, string mailbox = null) { if (!Authed) throw new NotAuthenticatedException(); lock (sequenceLock) { PauseIdling(); SelectMailbox(mailbox); string tag = GetTag(); string response = SendCommandGetResponse(tag + "UID SEARCH " + criteria.ToString()); List<uint> result = new List<uint>(); while (response.StartsWith("*")) { Match m = Regex.Match(response, @"^\* SEARCH (.+)"); if (m.Success) { string[] v = m.Groups[1].Value.Trim().Split(' '); foreach (string s in v) { try { result.Add(Convert.ToUInt32(s)); } catch(FormatException) { } } } response = GetResponse(); } ResumeIdling(); if (!IsResponseOK(response, tag)) throw new BadServerResponseException(response); return result.ToArray(); } }
private static SearchCondition Join(string condition, SearchCondition left, params SearchCondition[] right) { condition = condition.ToUpper(); if (left.Operator != condition) left = new SearchCondition { Operator = condition, Conditions = new List<SearchCondition> { left } }; left.Conditions.AddRange(right); return left; }
/// <summary> /// Logically ORs multiple search conditions, meaning a message will be /// included in the search result set if it meets at least one of the /// conditions. /// </summary> /// <param name="other">A search condition to logically OR this /// SearchCondition instance with</param> /// <returns>A new SearchCondition instance which can be further chained /// with other search conditions.</returns> public SearchCondition Or(SearchCondition other) { return(Join("OR", this, other)); }
/// <summary> /// Searches the specified mailbox for messages that match the given /// searching criteria. /// </summary> /// <param name="criteria">A search criteria expression. Only messages /// that match this expression will be included in the result set returned /// by this method.</param> /// <param name="mailbox">The mailbox that will be searched. If this parameter is /// omitted, the value of the DefaultMailbox property is used to determine the mailbox /// to operate on.</param> /// <exception cref="NotAuthenticatedException">Thrown if the method was called /// in a non-authenticated state, i.e. before logging into the server with /// valid credentials.</exception> /// <exception cref="BadServerResponseException">Thrown if the search could /// not be completed. The message property of the exception contains the error /// message returned by the server.</exception> /// <returns>An array of unique identifier (UID) message attributes which /// can be used with the GetMessage family of methods to download mail /// messages.</returns> /// <remarks>A unique identifier (UID) is a 64-bit value assigned to each /// message which uniquely identifies the message within a mailbox. No two /// messages in a mailbox share the the same UID.</remarks> /// <include file='Examples.xml' path='S22/Imap/ImapClient[@name="Search"]/*'/> public List<long> Search(SearchCondition criteria) { return this.Search(criteria.ToString()); }
/// <summary> /// Logically negates search conditions, meaning a message will only /// be included in the search result set if the specified conditions /// are not met. /// </summary> /// <param name="other">A search condition that must not be met by a /// message for it to be included in the search result set</param> /// <returns>A new SearchCondition instance which can be further chained /// with other search conditions.</returns> public SearchCondition Not(SearchCondition other) { return(Join("NOT", this, other)); }
/// <summary> /// Logically ANDs multiple search conditions, meaning a message will only /// be included in the search result set if all conditions are met. /// </summary> /// <param name="other">A search condition to logically AND this /// SearchCondition instance with</param> /// <returns>A new SearchCondition instance which can be further chained /// with other search conditions.</returns> public SearchCondition And(SearchCondition other) { return(Join(string.Empty, this, other)); }
/// <summary> /// Logically ORs multiple search conditions, meaning a message will be included in the search /// result if it meets at least either of the conditions. /// </summary> /// <param name="other">A search condition to logically OR this SearchCondition instance /// with.</param> /// <returns>A new SearchCondition instance which can be further chained with other search /// conditions.</returns> /// <exception cref="ArgumentNullException">The other parameter is null.</exception> public SearchCondition Or(SearchCondition other) { other.ThrowIfNull("other"); return(Join("OR", this, other)); }
/// <summary> /// Logically negates search conditions, meaning a message will only be included in the search /// result if the specified conditions are not met. /// </summary> /// <param name="other">A search condition that must not be met by a message for it to be /// included in the search result set.</param> /// <returns>A new SearchCondition instance which can be further chained with other search /// conditions.</returns> /// <exception cref="ArgumentNullException">The other parameter is null.</exception> public SearchCondition Not(SearchCondition other) { other.ThrowIfNull("other"); return(Join("NOT", this, other)); }
/// <summary> /// Logically ANDs multiple search conditions, meaning a message will only be included in the /// search result if both of the ANDed conditions are met. /// </summary> /// <param name="other">A search condition to logically AND this SearchCondition instance /// with.</param> /// <returns>A new SearchCondition instance which can be further chained with other search /// conditions.</returns> /// <exception cref="ArgumentNullException">The other parameter is null.</exception> public SearchCondition And(SearchCondition other) { other.ThrowIfNull("other"); return(Join(string.Empty, this, other)); }