<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>brool &#187; imap</title>
	<atom:link href="http://www.brool.com/index.php/tag/imap/feed" rel="self" type="application/rss+xml" />
	<link>http://www.brool.com</link>
	<description>brool \brool\ (n.) : a low roar; a deep murmur or humming</description>
	<lastBuildDate>Fri, 20 Jan 2012 07:58:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Using MissingPy</title>
		<link>http://www.brool.com/index.php/using-missingpy</link>
		<comments>http://www.brool.com/index.php/using-missingpy#comments</comments>
		<pubDate>Fri, 20 Mar 2009 02:15:00 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[imap]]></category>
		<category><![CDATA[missingpy]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.brool.com/?p=209</guid>
		<description><![CDATA[For comparison purposes, I was rewriting the silly little e-mail digest program in Haskell, using Python libraries for the IMAP interface (it&#8217;s available on Github). It&#8217;s hard to beat Python&#8217;s amazing collection of libraries. Cabal / hackage isn&#8217;t bad, but it doesn&#8217;t yet approach Python&#8217;s &#8220;batteries included&#8221; philosophy and ease of use. Anyway, I couldn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>For comparison purposes, I was rewriting the <a href="http://www.brool.com/index.php/creating-mail-digests-with-python-and-imap">silly little e-mail digest program</a> in Haskell, using Python libraries for the IMAP interface (it&#8217;s <a href="http://github.com/brool/digest/tree/master">available on Github</a>). It&#8217;s hard to beat Python&#8217;s amazing collection of libraries.  Cabal / hackage isn&#8217;t bad, but it doesn&#8217;t yet approach Python&#8217;s &#8220;batteries included&#8221; philosophy and ease of use.  Anyway, I couldn&#8217;t find an IMAP library for Haskell, so decided instead to try <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MissingPy">MissingPy</a> to interface into the Python IMAP library.  A quick overview/tutorial:</p>

<h3>Installing MissingPy</h3>
<p>I had an issue using Cabal to install MissingPy into my GHC 6.10 installation (Mac OS X).  I went into the directory that had been unpacked and modified Setup.hs:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="haskell"><pre class="de1"><span class="kw1">import</span> Distribution<span class="sy0">.</span>PackageDescription
<span class="kw1">import</span> Distribution<span class="sy0">.</span>PackageDescription<span class="sy0">.</span>Parse  <span class="co1">-- added this line</span>
<span class="kw1">import</span> Distribution<span class="sy0">.</span>Simple</pre></div></div></div></div></div></div></div>




<p>A cabal configure, build, and install of the package then installed everything.</p>

<h3>Basic Usage</h3>
<p>It&#8217;s easiest to play around with MissingPy in ghci.  Before you do anything you&#8217;ll need to initialize the interpreter with py_initialize and import any necessary modules with pyImport.  You can test by using pyRun_SimpleString:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="haskell"><pre class="de1"># :m Python<span class="sy0">.</span>Interpreter Python<span class="sy0">.</span>Objects Python<span class="sy0">.</span>Utils Python<span class="sy0">.</span>Exceptions
# py<span class="sy0">_</span>initialize
# pyRun<span class="sy0">_</span>SimpleString <span class="st0">&quot;print 'hello'&quot;</span>
hello</pre></div></div></div></div></div></div></div>




<p>The simplest useful way to execute python code is to use pyRun_String.  For example:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="haskell"><pre class="de1"><span class="co1">-- add 1 and 2 in Python</span>
<span class="co1">-- can also use Py_file_input or Py_single_input for different handling of the context</span>
addem <span class="sy0">=</span> pyRun<span class="sy0">_</span>String <span class="st0">&quot;1+2&quot;</span> Py<span class="sy0">_</span>eval<span class="sy0">_</span>input <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">&gt;&gt;=</span> fromPyObject <span class="sy0">::</span> <span class="kw4">IO</span> <span class="kw4">Integer</span></pre></div></div></div></div></div></div></div>




<p>There are also the callByName and pyObject_Call methods for more complicated scenarios.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="haskell"><pre class="de1">callByName <span class="sy0">::</span> <span class="kw4">String</span>            <span class="co1">-- ^ Object\/function name</span>
           <span class="sy0">-&gt;</span> <span class="br0">&#91;</span>PyObject<span class="br0">&#93;</span>        <span class="co1">-- ^ List of non-keyword parameters</span>
           <span class="sy0">-&gt;</span> <span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw4">String</span><span class="sy0">,</span> PyObject<span class="br0">&#41;</span><span class="br0">&#93;</span> <span class="co1">-- ^ List of keyword parameters</span>
           <span class="sy0">-&gt;</span> <span class="kw4">IO</span> PyObject
&nbsp;
pyObject<span class="sy0">_</span>Call <span class="sy0">::</span> PyObject       <span class="co1">-- ^ Object to call</span>
              <span class="sy0">-&gt;</span> <span class="br0">&#91;</span>PyObject<span class="br0">&#93;</span>     <span class="co1">-- ^ List of non-keyword parameters (may be empty)</span>
              <span class="sy0">-&gt;</span> <span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw4">String</span><span class="sy0">,</span> PyObject<span class="br0">&#41;</span><span class="br0">&#93;</span> <span class="co1">-- ^ List of keyword parameters (may be empty)</span>
              <span class="sy0">-&gt;</span> <span class="kw4">IO</span> PyObject    <span class="co1">-- ^ Return value</span>
&nbsp;
<span class="co1">-- example 1: create an IMAP instance</span>
imap <span class="sy0">&lt;-</span> callByName <span class="st0">&quot;imaplib.IMAP4_SSL&quot;</span> <span class="br0">&#91;</span>imap<span class="sy0">_</span>hostname<span class="br0">&#93;</span> <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
<span class="co1">-- call &quot;foo.bar(p1,p2)&quot;</span>
bar <span class="sy0">&lt;-</span> getattr foo <span class="st0">&quot;bar&quot;</span>
result <span class="sy0">&lt;-</span> pyObject<span class="sy0">_</span>Call bar <span class="br0">&#91;</span>p1<span class="sy0">,</span>p2<span class="br0">&#93;</span> <span class="br0">&#91;</span><span class="br0">&#93;</span></pre></div></div></div></div></div></div></div>




<h3>Manipulating Python Objects</h3>
<p>The fromPyObject and toPyObject handle marshaling of objects from Haskell to Python and vice versa.  There are some handy functions for doing common operations on Python objects that are especially useful from the REPL: reprOf (like Python repr), strOf (Python str), showPyObject (shows the type and repr), and dirPyObject (like the Python dir()).</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="haskell"><pre class="de1"># g <span class="sy0">&lt;-</span> pyRun<span class="sy0">_</span>String <span class="st0">&quot;(1,2,'hello')&quot;</span> Py<span class="sy0">_</span>eval<span class="sy0">_</span>input <span class="br0">&#91;</span><span class="br0">&#93;</span>
# showPyObject g
<span class="st0">&quot;&lt;type 'tuple'&gt;: (1, 2, 'hello')&quot;</span>
# reprOf g
<span class="st0">&quot;(1, 2, 'hello')&quot;</span>
# strOf g
<span class="st0">&quot;(1, 2, 'hello')&quot;</span>
# dirPyObject g
<span class="br0">&#91;</span><span class="st0">&quot;__add__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__class__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__contains__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__delattr__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__doc__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__eq__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__ge__&quot;</span><span class="sy0">,</span>
<span class="st0">&quot;__getattribute__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__getitem__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__getnewargs__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__getslice__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__gt__&quot;</span><span class="sy0">,</span>
<span class="st0">&quot;__hash__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__init__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__iter__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__le__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__len__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__lt__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__mul__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__ne__&quot;</span><span class="sy0">,</span>
<span class="st0">&quot;__new__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__reduce__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__reduce_ex__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__repr__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__rmul__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__setattr__&quot;</span><span class="sy0">,</span><span class="st0">&quot;__str__&quot;</span><span class="br0">&#93;</span></pre></div></div></div></div></div></div></div>




<h3>Dealing with Data</h3>
<p>Tuples look like lists when they are returned.  There is no conversion of tuples in the toPyObject call, so you&#8217;ll need to just convert a list and then convert it to a tuple with pyList_AsTuple.  Passing &#8220;None,&#8221; &#8220;True,&#8221; or &#8220;False&#8221; is trickier; the only way I found to do it was create an instance of the value and use it in subsequent calls.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="haskell"><pre class="de1"># a
<span class="br0">&#91;</span><span class="nu0">1</span><span class="sy0">,</span><span class="nu0">2</span><span class="br0">&#93;</span>
# b <span class="sy0">&lt;-</span> toPyObject a
# reprOf b
<span class="st0">&quot;[1L, 2L]&quot;</span>
# pyList<span class="sy0">_</span>AsTuple b <span class="sy0">&gt;&gt;=</span> reprOf
<span class="st0">&quot;(1L, 2L)&quot;</span>
&nbsp;
<span class="co1">-- get &quot;True,&quot; &quot;False,&quot; and &quot;None&quot;</span>
none <span class="sy0">&lt;-</span> pyRun<span class="sy0">_</span>String <span class="st0">&quot;None&quot;</span> Py<span class="sy0">_</span>eval<span class="sy0">_</span>input <span class="br0">&#91;</span><span class="br0">&#93;</span>
pyTrue <span class="sy0">&lt;-</span> pyRun<span class="sy0">_</span>String <span class="st0">&quot;True&quot;</span> Py<span class="sy0">_</span>eval<span class="sy0">_</span>input <span class="br0">&#91;</span><span class="br0">&#93;</span>
pyFalse <span class="sy0">&lt;-</span> pyRun<span class="sy0">_</span>String <span class="st0">&quot;False&quot;</span> Py<span class="sy0">_</span>eval<span class="sy0">_</span>input <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
<span class="co1">-- try it out</span>
# r <span class="sy0">&lt;-</span> pyRun<span class="sy0">_</span>String <span class="st0">&quot;1==1&quot;</span> Py<span class="sy0">_</span>eval<span class="sy0">_</span>input <span class="br0">&#91;</span><span class="br0">&#93;</span>
# r <span class="sy0">==</span> pyTrue
True</pre></div></div></div></div></div></div></div>




<h3>Passing Haskell Objects</h3>
<p>If you want to call into functions without having to deal with Python objects, there are a couple of calls that automatically marshal the objects back and forth for you (all suffixed with &#8220;Hs&#8221;), although they turn out to be less than useful in most situations, since a) the parameters passed in must all be the same type, and b) extracting most return objects from Python is painful.  </p>

<table border="1px solid" width="100%">
<tr><th>call</th><th>invoked upon</th><th>returns</th></tr>
<tr><td>callByNameHs</td><td>Object/function name</td><td>Haskell</td></tr>
<tr><td>pyObject_CallHs</td><td>PyObject</td><td>Haskell</td></tr>
<tr><td>pyObject_Hs</td><td>PyObject</td><td>Python</td></tr>
<tr><td>pyObject_RunHs</td><td>PyObject</td><td>nothing</td></tr>
<tr><td>callMethodHs</td><td>PyObject + method name</td><td>Haskell</td></tr>
<tr><td>runMethodHs</td><td>PyObject + method name</td><td>nothing</td></tr>
</table>
<br/>

<h3>Exceptions</h3>
<p>Python exceptions can be caught and handled;  probably the easiest default way to do this is to use handlePy in conjunction with the ex2ioerr handler, which will automatically print the exception and fail.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="haskell"><pre class="de1">addem <span class="sy0">=</span> handlePy exc2ioerror <span class="sy0">$</span> 
           <span class="kw1">do</span> r <span class="sy0">&lt;-</span> pyRun<span class="sy0">_</span>String <span class="st0">&quot;1/0&quot;</span> Py<span class="sy0">_</span>eval<span class="sy0">_</span>input <span class="br0">&#91;</span><span class="br0">&#93;</span>
              fromPyObject r <span class="sy0">::</span> <span class="kw4">IO</span> <span class="kw4">Integer</span>
&nbsp;
# addem
<span class="sy0">***</span> Exception: user <span class="kw3">error</span> <span class="br0">&#40;</span>Python <span class="sy0">&lt;</span><span class="kw1">type</span> 'exceptions<span class="sy0">.</span>ZeroDivisionError'<span class="sy0">&gt;</span>: integer division <span class="kw3">or</span> modulo by zero<span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>


]]></content:encoded>
			<wfw:commentRss>http://www.brool.com/index.php/using-missingpy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Mail Digests with Python and IMAP</title>
		<link>http://www.brool.com/index.php/creating-mail-digests-with-python-and-imap</link>
		<comments>http://www.brool.com/index.php/creating-mail-digests-with-python-and-imap#comments</comments>
		<pubDate>Mon, 29 Dec 2008 05:00:47 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[imap]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.brool.com/?p=106</guid>
		<description><![CDATA[There should be a word for &#8220;effort undertaken even though you&#8217;re sure, somewhere, somebody has written something for it already, or maybe it&#8217;s already a Linux command.&#8221; I get the distinct feeling that this utility already exists, but I googled to no avail. I have a bunch of e-mail boxes, some incredibly infrequently used, but [...]]]></description>
			<content:encoded><![CDATA[<p>There should be a word for &#8220;effort undertaken even though you&#8217;re sure, somewhere, somebody has written something for it already, or maybe it&#8217;s already a Linux command.&#8221;  I get the distinct feeling that this utility already exists, but I googled to no avail.</p>

<p>I have a bunch of e-mail boxes, some incredibly infrequently used, but I wanted to be sure that I noticed any important messages without having to go to all the work of, you know, actually <i>logging into them</i>.  So I created a quick little digest utility that will on a daily cron.</p>

<p>This entire process was about two times more painful than it really needed to be because using the IMAP libraries in Python really requires knowing the <a href="http://www.isi.edu/in-notes/rfc3501.txt">IMAP specification</a>, and I tried to be lazy and not bother reading the specification first, so I got stuck for a bit on how to search an IMAP mailbox properly.</p>

<h3>TL;DR Version</h3>
<p>You see, <code>imap.search(None, 'ALL')</code> was working fine, but I wanted to get all of yesterday&#8217;s messages.  It turns out that instead of using:</p>
<code>imap.search(None, 'SINCE 1-Dec-2008')</code>
<p>you just need to have every token be a separate parameter:</p>
<code>imap.search(None, 'SINCE', '1-Dec-2008')</code>
<p>&#8230;which seems unpythonic to me, but no matter.</p>

<h3>Testing From The Console</h3>
<p>It helped me to be able to interact with the IMAP servers from the command line.  Usually, I just use telnet to do this, but the IMAP servers that I was working with were SSL only.  There&#8217;s an easy way to deal with this, at least under Debian; just install the telnet-ssl package and then log into it like:</p>

<code>telnet-ssl -z ssl imap.gmail.com</code>

<p>IMAP takes arbitrary sequence IDs at the start of every command.  The starting login sequence is something like:</p>
<code>0001 LOGIN userid password
0002 SELECT INBOX
0003 SEARCH SINCE 27-Dec-2008
</code>

<h3>Turning On Debug Information</h3>
<p>Alternatively, you can just turn on the debug information for the IMAP libraries, by doing something like:</p>
<pre>imaplib.Debug = 99
imap = imaplib.IMAP4_SSL("imap.gmail.com")</pre>
<p>&#8230; and then go through the standard sequence.</p>

<p>Code can be found on <a href="http://github.com/brool/digest/tree/master">github</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.brool.com/index.php/creating-mail-digests-with-python-and-imap/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

