{"id":3550,"date":"2011-10-21T01:19:45","date_gmt":"2011-10-21T01:19:45","guid":{"rendered":"http:\/\/blogs.n1zyy.com\/n1zyy\/?p=3550"},"modified":"2011-10-21T01:19:45","modified_gmt":"2011-10-21T01:19:45","slug":"imap-search-musings","status":"publish","type":"post","link":"https:\/\/blogs.n1zyy.com\/n1zyy\/2011\/10\/21\/imap-search-musings\/","title":{"rendered":"IMAP Search Musings"},"content":{"rendered":"<p>I think most geeks get a ton of email. I&#8217;ve been rather selective in what lists I join (and what mail I just auto-delete at the server level), so I only get perhaps a couple hundred emails a day now.<\/p>\n<p>For various ridiculous reasons, searching a mailbox is hard. Most of my mail clients will do it, but sometimes I really want to do it myself because I want to be more exacting. Lately I&#8217;ve been tinkering more and more with using IMAP from the command line. Partially it&#8217;s that IMAP is really just a little bit unusual and kind of intriguing. But mostly, it&#8217;s just that, from time to time, it&#8217;s easier for me to just send some manual IMAP commands if I know what I&#8217;m doing. (For example, I have absolutely no idea how to subscribe to a particular folder in any of the mail clients I have available. I could wade through the menus and maybe find it, but it&#8217;s easier for me to just <a title=\"Using Ruby's Net::IMAP to subscribe to a mailbox folder\" href=\"https:\/\/gist.github.com\/1203568\">use Net::IMAP to subscribe to the folder<\/a>.)<\/p>\n<p>Like most implementations, Ruby&#8217;s Net::IMAP library provides a <a title=\"Ruby Net::IMAP search\" href=\"http:\/\/ruby-doc.org\/stdlib-1.9.2\/libdoc\/net\/imap\/rdoc\/Net\/IMAP.html#method-i-search\">search<\/a> method. And, like most implementations, it does a very poor job of documenting what is supported. At the risk of sounding like I&#8217;ve lost my mind, I actually found the <a title=\"IMAP RFC 3501\" href=\"http:\/\/tools.ietf.org\/html\/rfc3501#section-6.4.4\">IMAP RFC (3501)<\/a> to be the easiest bit of documentation to understand. Below are some examples:<\/p>\n<p>You can chain keys, so the following is a valid search command:<\/p>\n<p><code>FROM \"matt\" SUBJECT \"bacon\"<\/code><\/p>\n<p>But what isn&#8217;t abundantly clear is that search terms are combined with a logical AND, so the above will only match mail from Matt with &#8220;bacon&#8221; in the subject line.<\/p>\n<p>This appears to be the way to get a logical OR instead:<\/p>\n<p><code>(FROM \"matt\") OR (SUBJECT \"bacon\")<\/code><\/p>\n<p>After spending a while trying to get all possible keys for a text search &#8212; e.g., <tt>(FROM \"foo\") OR (SUBJECT \"foo\") OR (CC \"foo\")...<\/tt> &#8212; I realized that there&#8217;s an easier way: the TEXT key, which searches headers and the body. So for my generic search method, the search simply became <tt>TEXT \"foo\"<\/tt>.<\/p>\n<p>You may also find some of the other keys interesting, like the ability to search for <tt>RECENT<\/tt> or <tt>FLAGGED<\/tt>. I don&#8217;t intend to provide an exhaustive list here, however.<\/p>","protected":false},"excerpt":{"rendered":"<p>I think most geeks get a ton of email. I&#8217;ve been rather selective in what lists I join (and what mail I just auto-delete at the server level), so I only get perhaps a couple hundred emails a day now. &hellip; <a href=\"https:\/\/blogs.n1zyy.com\/n1zyy\/2011\/10\/21\/imap-search-musings\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3550","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/posts\/3550","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/comments?post=3550"}],"version-history":[{"count":0,"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/posts\/3550\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/media?parent=3550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/categories?post=3550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.n1zyy.com\/n1zyy\/wp-json\/wp\/v2\/tags?post=3550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}