<?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>The GITS Blog &#187; programming</title>
	<atom:link href="http://ginstrom.com/scribbles/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://ginstrom.com/scribbles</link>
	<description>Random scribbling about programming, translation, and Japan</description>
	<lastBuildDate>Sun, 07 Mar 2010 08:38:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Simple Ajax with cherrypy and jQuery</title>
		<link>http://ginstrom.com/scribbles/2010/03/07/simple-ajax-with-cherrypy-and-jquery/</link>
		<comments>http://ginstrom.com/scribbles/2010/03/07/simple-ajax-with-cherrypy-and-jquery/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 08:27:04 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1503</guid>
		<description><![CDATA[All the cool kids these days are putting Ajax into their web applications. Ajax is great for when you want to update data on a page without reloading the entire page. Most of the Ajax tutorials use PHP, so I want to show here how easy it is to do Ajax with cherrpy.
Ajax stands for [...]]]></description>
			<content:encoded><![CDATA[<p>All the cool kids these days are putting Ajax into their web applications. Ajax is great for when you want to update data on a page without reloading the entire page. Most of the Ajax tutorials use PHP, so I want to show here how easy it is to do Ajax with <a href="http://www.cherrypy.org/">cherrpy</a>.</p>
<p>Ajax stands for "asynchronous JavaScript and XML," but these days <a href="http://www.json.org/">json</a> is often used as a lighter-weight alternative to XML. In this tutorial, I'm therefore going to show how to use the python <a href="http://pypi.python.org/pypi/simplejson/">simplejson</a> library to enable communication between python and JavaScript using json.</p>
<p>What you will need for this tutorial:</p>
<ul>
<li><a href="http://www.cherrypy.org/">cherrpy</a></li>
<li><a href="http://pypi.python.org/pypi/simplejson/">simplejson</a></li>
<li><a href="http://jquery.com/">jQuery</a></li>
<li>The <a href="/code/ajax_cherrypy_sample.zip">sample project</a></li>
</ul>
<p>You can get cherrypy and simplejson from pypi via easy_install; there's a copy of jQuery in my <a href="/code/ajax_cherrypy_sample.zip">sample project</a>. The sample project consists of three files, in the following structure:</p>
<pre>
ajax_app.py
media/
  + jquery-1.4.2.min.js
  | index.html
</pre>
<p>First, I'll show the HTML file:</p>
<div class="dean_ch" style="white-space: wrap;">
&lt;html&gt;<br />
&lt;head&gt;<br />
&nbsp; &nbsp; &lt;title&gt;AJAX with jQuery and cherrypy&lt;/title&gt;<br />
&nbsp; &nbsp; &lt;script type=&quot;text/javascript&quot; src=&quot;/media/jquery-1.4.2.min.js&quot;&gt;&lt;/script&gt;<br />
&lt;script type=&quot;text/javascript&quot;&gt;<br />
&nbsp; &nbsp; $(function() {<br />
&nbsp; &nbsp; // When the testform is submitted&#8230;<br />
&nbsp; &nbsp; $(&quot;#testform&quot;).submit(function() {<br />
&nbsp; &nbsp; &nbsp; &nbsp; // post the form values via AJAX&#8230;<br />
&nbsp; &nbsp; &nbsp; &nbsp; var postdata = {name: $(&quot;#name&quot;).val()} ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $.post('/submit', postdata, function(data) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // and set the title with the result<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $(&quot;#title&quot;).html(data['title']) ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;});<br />
&nbsp; &nbsp; &nbsp; &nbsp; return false ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; });<br />
&nbsp; &nbsp; });<br />
&lt;/script&gt;<br />
&lt;/head&gt;<br />
&nbsp; &nbsp; &lt;body&gt;<br />
&nbsp; &nbsp; &lt;h1 id=&quot;title&quot;&gt;What's your name?&lt;/h1&gt;</p>
<p>&nbsp; &nbsp; &lt;form id=&quot;testform&quot; action=&quot;#&quot; method=&quot;post&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;label for=&quot;name&quot;&gt;Name:&lt;/label&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;input type=&quot;text&quot; id=&quot;name&quot; /&gt; &lt;br /&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;input type=&quot;submit&quot; value=&quot;Set&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;/p&gt;<br />
&nbsp; &nbsp; &lt;/form&gt;<br />
&nbsp; &nbsp; &lt;/body&gt;<br />
&lt;/html&gt;</div>
<p>Let's see what this is doing. In the body, you've got a title tag, and bog standard HTML form, which asks for a name.</p>
<p>In the head, you've got an include to the jQuery library, and the following JavaScript code:</p>
<div class="dean_ch" style="white-space: wrap;">
&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// When the testform is submitted&#8230;</span><br />
&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&quot;#testform&quot;</span><span class="br0">&#41;</span>.<span class="me1">submit</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// post the form values via AJAX&#8230;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> postdata = <span class="br0">&#123;</span><span class="kw3">name</span>: $<span class="br0">&#40;</span><span class="st0">&quot;#name&quot;</span><span class="br0">&#41;</span>.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#125;</span> ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $.<span class="me1">post</span><span class="br0">&#40;</span><span class="st0">'/submit'</span>, postdata, <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// and set the title with the result</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&quot;#title&quot;</span><span class="br0">&#41;</span>.<span class="me1">html</span><span class="br0">&#40;</span>data<span class="br0">&#91;</span><span class="st0">'title'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span> ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
<p>The initial <code> $(function() </code> statement is a jQuery construct that says, "When the page loads, execute this anonymous function." That function then creates a callback for the submit event of the element with id "testform" (the form). When the form is submitted, the jQuery <code>post</code> function is executed, which is where the magic happens.</p>
<p><a href="http://api.jquery.com/jQuery.post/">jQuery.post</a> is an Ajax method. The first argument is the URL to post to ("/submit"); the second argument is the data to send in the post (the "name" value from the form); and the third argument is the callback to call with the data we receive from the post.</p>
<p>The function then takes this data, and uses its "title" element to update the title of the page.</p>
<p>Next, here's the ajax_app.py file:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">import</span> cherrypy<br />
<span class="kw1">import</span> <span class="kw3">webbrowser</span><br />
<span class="kw1">import</span> <span class="kw3">os</span><br />
<span class="kw1">import</span> simplejson<br />
<span class="kw1">import</span> <span class="kw3">sys</span></p>
<p>MEDIA_DIR = <span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">abspath</span><span class="br0">&#40;</span><span class="st0">&quot;.&quot;</span><span class="br0">&#41;</span>, u<span class="st0">&quot;media&quot;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">class</span> AjaxApp<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; @cherrypy.<span class="me1">expose</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> index<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">open</span><span class="br0">&#40;</span><span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">join</span><span class="br0">&#40;</span>MEDIA_DIR, u<span class="st0">'index.html'</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; @cherrypy.<span class="me1">expose</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> submit<span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; cherrypy.<span class="me1">response</span>.<span class="me1">headers</span><span class="br0">&#91;</span><span class="st0">'Content-Type'</span><span class="br0">&#93;</span> = <span class="st0">'application/json'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> simplejson.<span class="me1">dumps</span><span class="br0">&#40;</span><span class="kw2">dict</span><span class="br0">&#40;</span>title=<span class="st0">&quot;Hello, %s&quot;</span> % name<span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>config = <span class="br0">&#123;</span><span class="st0">'/media'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><span class="st0">'tools.staticdir.on'</span>: <span class="kw2">True</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">'tools.staticdir.dir'</span>: MEDIA_DIR,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p><span class="kw1">def</span> open_page<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw3">webbrowser</span>.<span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;http://127.0.0.1:8080/&quot;</span><span class="br0">&#41;</span><br />
cherrypy.<span class="me1">engine</span>.<span class="me1">subscribe</span><span class="br0">&#40;</span><span class="st0">'start'</span>, open_page<span class="br0">&#41;</span><br />
cherrypy.<span class="me1">tree</span>.<span class="me1">mount</span><span class="br0">&#40;</span>AjaxApp<span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="st0">'/'</span>, config=config<span class="br0">&#41;</span><br />
cherrypy.<span class="me1">engine</span>.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>First, the <code>AjaxApp</code> class is our application. It's pretty simple, having only two methods: <code>index</code> and <code>submit</code>. </p>
<p>When the index method is called, the app opens the index file and returns it. </p>
<p>The submit method is our Ajax method; when it is called with the form data, we use the information to create a new title, and pass that back as json data using <a href="http://svn.red-bean.com/bob/simplejson/tags/simplejson-1.3/docs/module-simplejson.html#dumps">simplejson.dumps</a>. The JavaScript function that called this method can then use the data to update the page content.</p>
<p>This little piece of code is a convenience for development; when you run the cherrpy app, it loads the index page in your web browser.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> open_page<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw3">webbrowser</span>.<span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;http://127.0.0.1:8080/&quot;</span><span class="br0">&#41;</span><br />
cherrypy.<span class="me1">engine</span>.<span class="me1">subscribe</span><span class="br0">&#40;</span><span class="st0">'start'</span>, open_page<span class="br0">&#41;</span></div>
<p>Finally, the last two lines mount the app, and start up the server. The "config" dict tells cherrpy to serve up static files from the "media" dir in the script's home directory.</p>
<p>If you download the sample project, unzip it, and run ajax_app.py, you should get the following screen (shown here with the name filled in):</p>
<div id="attachment_1506" class="wp-caption alignnone" style="width: 310px"><a href="http://ginstrom.com/scribbles/wp-content/uploads/2010/03/screen1.png"><img src="http://ginstrom.com/scribbles/wp-content/uploads/2010/03/screen1.png" alt="Ajax app -- step1" title="ajax_app1" width="300" height="175" class="size-full wp-image-1506" /></a><p class="wp-caption-text">Ajax app -- step 1</p></div>
<p>Here it is after filling in the name and clicking <strong>Set</strong>:</p>
<div id="attachment_1507" class="wp-caption alignnone" style="width: 310px"><a href="http://ginstrom.com/scribbles/wp-content/uploads/2010/03/screen2.png"><img src="http://ginstrom.com/scribbles/wp-content/uploads/2010/03/screen2.png" alt="Ajax app -- step 2" title="ajax_app2" width="300" height="175" class="alignnone size-full wp-image-1507" /></a><p class="wp-caption-text">Ajax app -- step 2</p></div>
<h3>When to use Ajax</h3>
<p>Ajax is useful when you want to update the page content without reloading the entire page. This is useful for CRUD apps when you want to do things like edit items in place, delete items, or add items.</p>
<h3>When not to use Ajax</h3>
<p>Since Ajax actions don't correspond to URIs, you can't bookmark Ajax actions, send links to friends, or use the back and forward buttons to navigate like in a normal website.</p>
<p>For this reason, avoid Ajax if you want certain application states to be navigable as URIs. For example, if you have a calendar application, and use Ajax to show all the data, the user won't have any way to bookmark an event on December 12th, 2011. Likewise, if you use an Ajax data grid to show tables of data, you won't be able to email your data views to your colleagues.</p>
<p>One middle way is to offer a "permalink" for each Ajax view, which allows for bookmarking, sending links, etc. This still breaks the back-button functionality, but may be worth the trade-off.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2010/03/07/simple-ajax-with-cherrypy-and-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Implementing IDocHostUIHandler in a C++ WTL/ATL project</title>
		<link>http://ginstrom.com/scribbles/2009/11/18/implementing-idochostuihandler/</link>
		<comments>http://ginstrom.com/scribbles/2009/11/18/implementing-idochostuihandler/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 22:41:13 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[IDocHostUIHandler]]></category>
		<category><![CDATA[web browser]]></category>
		<category><![CDATA[wtl]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1370</guid>
		<description><![CDATA[I recently implemented IDocHostUIHandler in one of my WTL projects hosting the web browser. You need to implement this interface if you want to do things like control the context menu of the web browser.
I had to go spelunking in various forums and documentation to piece together how to do this, and I never found [...]]]></description>
			<content:encoded><![CDATA[<p>I recently implemented <a href="http://msdn.microsoft.com/en-us/library/aa753260%28VS.85%29.aspx">IDocHostUIHandler</a> in one of my <a href="http://wtl.sourceforge.net/">WTL</a> projects hosting the web browser. You need to implement this interface if you want to do things like control the context menu of the web browser.</p>
<p>I had to go spelunking in various forums and documentation to piece together how to do this, and I never found the complete story online, so I thought I'd save any future searchers some trouble. I only did this in Visual Studio 2008, but I've done similar things in VS 2005, so it should work there also.</p>
<p>You should already have a WTL project with an .idl file that implements a COM server. If not, create a new WTL project with the wizard named "MyProject", and choose the option to make it a COM server.</p>
<h3>Add an ATL Simple Object</h3>
<p>Next, add a new class to your project, and select the type "ATL Simple Object."</p>
<p>Here's where you might hit your first snag. You might see the following error dialog:</p>
<div id="attachment_1379" class="wp-caption alignnone" style="width: 496px"><img src="http://ginstrom.com/scribbles/wp-content/uploads/2009/11/err_only_mfc1.png" alt="Error, only MFC projects please" title="Error only MFC" width="486" height="185" class="size-full wp-image-1379" /><p class="wp-caption-text">ATL classes can only be added to MFC EXE and MFC Regular DLL projects or projects with full ATL support</p></div>
<p>"I'm using the ATL, you idiot!" you yell vainly at your computer screen. But alas, the compiler gods did not consider that you might want to use something as esoteric as the WTL for your GUI project, when you have the obviously superior choice of MFC.</p>
<p>To convince Visual Studio that yes, you do deserve to add an ATL Simple Object to your project, you've got to modify the file "VS Root/VC/VCWizards/1033/common.js". Specifically, you've got to have the function <code>IsATLProject</code> return <code>true</code>.</p>
<p>On the Internet, you'll see all sorts of fixes to this function, but I just cut to the chase:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw2">function</span> IsATLProject<span class="br0">&#40;</span>oProj<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// I promise that I will use this only for good and not evil.</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span> ;<br />
&nbsp; &nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8230;</div>
<p>Try adding the object again; this time, you should be successful. Name your class something descriptive, like "MyHandler" ( <img src='http://ginstrom.com/scribbles/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ), and accept all the defaults.</p>
<h3>Modify the .idl file</h3>
<p>Now go into your .idl file, and make some edits. First, <code>import "atliface.idl"</code>, and <code>#include "olectl.h"</code>. The top of your file should now look like this:</p>
<div class="dean_ch" style="white-space: wrap;">
import <span class="st0">&quot;oaidl.idl&quot;</span>;<br />
import <span class="st0">&quot;ocidl.idl&quot;</span>;<br />
import <span class="st0">&quot;atliface.idl&quot;</span>;</p>
<p><span class="co2">#include &quot;olectl.h&quot;</span></div>
<p>Now, go to your IMyHandler interface, and change the base class from <code>IDispatch</code> to <code>IDocHostUIHandlerDispatch</code>, like so:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="br0">&#91;</span><br />
&nbsp; &nbsp; object,<br />
&nbsp; &nbsp; uuid<span class="br0">&#40;</span><span class="nu0">12345678</span><span class="nu0">-1234</span><span class="nu0">-1234</span><span class="nu0">-1234</span>-123456789ABC<span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; dual,<br />
&nbsp; &nbsp; nonextensible,<br />
&nbsp; &nbsp; helpstring<span class="br0">&#40;</span><span class="st0">&quot;IMyHandler Interface&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; pointer_default<span class="br0">&#40;</span>unique<span class="br0">&#41;</span><br />
<span class="br0">&#93;</span><br />
<span class="kw1">interface</span> IMyHandler : IDocHostUIHandlerDispatch<span class="br0">&#123;</span><br />
<span class="br0">&#125;</span>;</div>
<h3>Modify your MyHandler.h file</h3>
<p>Go into your CMyHandler class file, and <code>#include "Atliface.h"</code>. Next, add an entry to your COM map for <code>IDocHostUIHandlerDispatch</code>. The top of your file should now look something like this:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="co2">#pragma once</span><br />
<span class="co2">#include &quot;resource.h&quot; &nbsp; &nbsp; &nbsp; // main symbols</span><br />
<span class="co2">#include &quot;Atliface.h&quot;</span><br />
<span class="co2">#include &quot;MyProject.h&quot;</span></p>
<p><span class="co2">#if defined(_WIN32_WCE) &amp;&amp; !defined(_CE_DCOM) &amp;&amp; !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)</span><br />
<span class="co2">#error &quot;Blah blah blah&quot;</span><br />
<span class="co2">#endif</span></p>
<p><span class="co1">// CMyHandler</span></p>
<p><span class="kw2">class</span> ATL_NO_VTABLE CMyHandler :<br />
&nbsp; &nbsp; <span class="kw2">public</span> CComObjectRootEx&lt;CComSingleThreadModel&gt;,<br />
&nbsp; &nbsp; <span class="kw2">public</span> CComCoClass&lt;CMyHandler, &amp;CLSID_MyHandler&gt;,<br />
&nbsp; &nbsp; <span class="kw2">public</span> IDispatchImpl&lt;IMyHandler, &amp;IID_MyHandler, &amp;LIBID_MyProject, <span class="coMULTI">/*wMajor =*/</span> <span class="nu0">1</span>, <span class="coMULTI">/*wMinor =*/</span> <span class="nu0">0</span>&gt;<br />
<span class="br0">&#123;</span><br />
<span class="kw2">public</span>:</p>
<p>&nbsp; &nbsp; CMyHandler<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>DECLARE_REGISTRY_RESOURCEID<span class="br0">&#40;</span>IDR_MYHANDLER<span class="br0">&#41;</span></p>
<p>
BEGIN_COM_MAP<span class="br0">&#40;</span>CMyHandler<span class="br0">&#41;</span><br />
&nbsp; &nbsp; COM_INTERFACE_ENTRY<span class="br0">&#40;</span>IMyHandler<span class="br0">&#41;</span><br />
&nbsp; &nbsp; COM_INTERFACE_ENTRY<span class="br0">&#40;</span>IDocHostUIHandlerDispatch<span class="br0">&#41;</span><br />
&nbsp; &nbsp; COM_INTERFACE_ENTRY<span class="br0">&#40;</span>IDispatch<span class="br0">&#41;</span><br />
END_COM_MAP<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<h3>Add skeletons for the IDocHostUIHandler methods</h3>
<p>Add skeletons for all the methods implemented by <code>IDocHostUIHandler</code>. You can simply copy and paste the method signatures from IDocHostUIHandlerDispatch in "Atliface.h". Now implement the method bodies so that they all return <code>E_NOTIMPL</code>.</p>
<h3>Compile your code</h3>
<p>Now compile, and make sure that everything's working. </p>
<p>Here's where you might hit another snag: by failing to show proper respect to the compiler gods above, you could see an obscure MIDL error when you try to compile. Even if you don't, I recommend compiling your .idl file manually just to be sure. Go to <strong>All Programs</strong> &gt;&gt; <strong>Visual Studio 200X</strong> &gt;&gt; <strong>Visual Studio Tools</strong> &gt;&gt; <strong>Command Prompt</strong> (this loads the command prompt with all your VS symbols defined). </p>
<p>Next, navigate to your source directory, and compile your .idl file:</p>
<div class="dean_ch" style="white-space: wrap;">
midl MyProject.idl</div>
<h3>Implement methods of interest</h3>
<p>Now, you can implement the methods you're interested in. For example, if you want to suppress the context menu, or show your own menu in its place:</p>
<div class="dean_ch" style="white-space: wrap;">
HRESULT STDMETHODCALLTYPE ShowContextMenu<span class="br0">&#40;</span>DWORD dwID, DWORD x, DWORD y, IUnknown *pcmdtReserved, IDispatch *pdispReserved, HRESULT *dwRetVal <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; *dwRetVal = S_OK;<br />
&nbsp; &nbsp; <span class="co1">// Show your own context menu here if you want.</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> S_OK;<br />
<span class="br0">&#125;</span></div>
<h3>Set the handler in your web browser</h3>
<p>In your OnCreate handler, set your handler in the web browser.</p>
<div class="dean_ch" style="white-space: wrap;">
&nbsp; &nbsp; CComObject&lt;CMyHandler&gt; *pUIH = <span class="kw2">NULL</span>;<br />
&nbsp; &nbsp; HRESULT hr = CComObject&lt;CMyHandler&gt;::<span class="me2">CreateInstance</span> <span class="br0">&#40;</span>&amp;pUIH<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>SUCCEEDED<span class="br0">&#40;</span>hr<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Make our custom DocHostUIHandler the window.external handler</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; CComQIPtr&lt;IDocHostUIHandlerDispatch&gt; pIUIH = pUIH;<br />
&nbsp; &nbsp; &nbsp; &nbsp; hr = m_view.<span class="me1">SetExternalUIHandler</span><span class="br0">&#40;</span>pIUIH<span class="br0">&#41;</span> ;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; ATLASSERT<span class="br0">&#40;</span>SUCCEEDED<span class="br0">&#40;</span>hr<span class="br0">&#41;</span><span class="br0">&#41;</span> ;</div>
<p>That's it. Compile and run.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/11/18/implementing-idochostuihandler/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Easy SFTP uploading with paramiko</title>
		<link>http://ginstrom.com/scribbles/2009/09/14/easy-sftp-uploading-with-paramiko/</link>
		<comments>http://ginstrom.com/scribbles/2009/09/14/easy-sftp-uploading-with-paramiko/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 08:58:33 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1276</guid>
		<description><![CDATA[paramiko makes it so easy to use SFTP that it's hard to believe it's legal in this day and age. Command Line Warriors has a wonderful post showing how to use paramiko to do SFTP uploads/downloads.
In this post, I want to share a small helper module called sftp (zip file) (code in post below) that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lag.net/paramiko/">paramiko</a> makes it so easy to use SFTP that it's hard to believe it's legal in this day and age. <a href="http://commandline.org.uk/">Command Line Warriors</a> has a wonderful post showing <a href="http://commandline.org.uk/python/sftp-python/">how to use paramiko to do SFTP uploads/downloads</a>.</p>
<p>In this post, I want to share a small helper module called <a href="/code/sftp.zip">sftp (zip file)</a> (code in post below) that wraps paramiko.SFTPClient and makes uploading/downloading via SFTP even simpler.</p>
<p>First, some usage</p>
<p><strong>Upload or download a file</strong></p>
<div class="dean_ch" style="white-space: wrap;">
server = sftp.<span class="me1">Server</span><span class="br0">&#40;</span><span class="st0">&quot;user&quot;</span>, <span class="st0">&quot;pass&quot;</span>, <span class="st0">&quot;example.com&quot;</span><span class="br0">&#41;</span><br />
<span class="co1"># upload a file</span><br />
server.<span class="me1">upload</span><span class="br0">&#40;</span><span class="st0">&quot;/local/path&quot;</span>, <span class="st0">&quot;/remote/path&quot;</span><span class="br0">&#41;</span><br />
<span class="co1"># download a file</span><br />
server.<span class="me1">download</span><span class="br0">&#40;</span><span class="st0">&quot;remote/path&quot;</span>, <span class="st0">&quot;/local/path&quot;</span><span class="br0">&#41;</span><br />
server.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p><strong>with statement also supported:</strong></p>
<div class="dean_ch" style="white-space: wrap;">
with sftp.<span class="me1">Server</span><span class="br0">&#40;</span><span class="st0">&quot;user&quot;</span>, <span class="st0">&quot;pass&quot;</span>, <span class="st0">&quot;example.com&quot;</span><span class="br0">&#41;</span> as server:<br />
&nbsp; &nbsp; server.<span class="me1">upload</span><span class="br0">&#40;</span><span class="st0">&quot;/local/path&quot;</span>, <span class="st0">&quot;/remote/path&quot;</span><span class="br0">&#41;</span></div>
<p>Finally, a demo recipe for uploading all the png files from a specified local directory to a specified directory on the server:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="co1"># needed for python 2.5</span><br />
<span class="kw1">from</span> <span class="kw3">__future__</span> <span class="kw1">import</span> with_statement</p>
<p><span class="kw1">import</span> sftp<br />
<span class="kw1">import</span> <span class="kw3">glob</span><br />
<span class="kw1">from</span> <span class="kw3">os</span> <span class="kw1">import</span> path</p>
<p>remote_dir = <span class="st0">&quot;/path/on/remote/server/&quot;</span></p>
<p>with sftp.<span class="me1">Server</span><span class="br0">&#40;</span><span class="st0">&quot;user&quot;</span>, <span class="st0">&quot;pass&quot;</span>, <span class="st0">&quot;www.example.com&quot;</span><span class="br0">&#41;</span> as server:<br />
&nbsp; &nbsp; <span class="kw1">for</span> image <span class="kw1">in</span> <span class="kw3">glob</span>.<span class="kw3">glob</span><span class="br0">&#40;</span><span class="st0">&quot;/local/path/to/*.png&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; base = path.<span class="me1">basename</span><span class="br0">&#40;</span>image<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">upload</span><span class="br0">&#40;</span>image, path.<span class="me1">join</span><span class="br0">&#40;</span>remote_dir, base<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
<p>Now, here's the code for my sftp module:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">import</span> paramiko</p>
<p><span class="kw1">class</span> Server<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Wraps paramiko for super-simple SFTP uploading and downloading.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, username, password, host, port=<span class="nu0">22</span><span class="br0">&#41;</span>:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">transport</span> = paramiko.<span class="me1">Transport</span><span class="br0">&#40;</span><span class="br0">&#40;</span>host, port<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">transport</span>.<span class="me1">connect</span><span class="br0">&#40;</span>username=username, password=password<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sftp</span> = paramiko.<span class="me1">SFTPClient</span>.<span class="me1">from_transport</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">transport</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> upload<span class="br0">&#40;</span><span class="kw2">self</span>, local, remote<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sftp</span>.<span class="me1">put</span><span class="br0">&#40;</span>local, remote<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> download<span class="br0">&#40;</span><span class="kw2">self</span>, remote, local<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sftp</span>.<span class="me1">get</span><span class="br0">&#40;</span>remote, local<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> close<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Close the connection if it's active<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">transport</span>.<span class="me1">is_active</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sftp</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">transport</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># with-statement support</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> __enter__<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> __exit__<span class="br0">&#40;</span><span class="kw2">self</span>, <span class="kw2">type</span>, value, tb<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/09/14/easy-sftp-uploading-with-paramiko/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>On rapid iteration</title>
		<link>http://ginstrom.com/scribbles/2009/06/07/on-rapid-iteration/</link>
		<comments>http://ginstrom.com/scribbles/2009/06/07/on-rapid-iteration/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 08:39:00 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1130</guid>
		<description><![CDATA[I think that one of the great strengths of interpreted languages like Python is the ability to iterate rapidly, due to the lack of a compilation step.
I've been reading Richard Feynmann's fascinating reminiscences in Surely You're Joking, Mr. Feynmann. The entire text is available online.
One passage that really struck me was where he described the [...]]]></description>
			<content:encoded><![CDATA[<p>I think that one of the great strengths of interpreted languages like Python is the ability to iterate rapidly, due to the lack of a compilation step.</p>
<p>I've been reading Richard Feynmann's fascinating reminiscences in <a href="http://en.wikipedia.org/wiki/Surely_You%27re_Joking,_Mr._Feynman!">Surely You're Joking, Mr. Feynmann</a>. The entire text is <a href="http://www.gorgorat.com/">available online</a>.</p>
<p>One passage that really struck me was where he described the cyclotrons at Princeton, MIT, and Cornell:</p>
<blockquote><p>
It reminded me of my lab at  home. Nothing at MIT had ever reminded  me of  my  lab at home.  I suddenly realized why Princeton was getting results. They were working with the instrument. They built  the instrument; they knew where everything was, they knew how everything worked, there was no engineer involved, except maybe  he was working  there too. It  was much smaller than the cyclotron at MIT, and "gold-plated"? &#8212; it was  the exact opposite. When they wanted to fix a vacuum, they'd drip glyptal on it,  so there were drops of glyptal on the floor. It was wonderful! Because they worked with it. They didn't have to sit in another room and push buttons! (Incidentally, they had a fire in  that  room, because of all the chaotic mess that they had  &#8212; too many  wires &#8212; and it destroyed the cyclotron. But I'd better not tell about that!)</p>
<p>(When I  got  to Cornell I  went to look  at the cyclotron there.  This<br />
cyclotron hardly required a room: It was about a yard across &#8212; the diameter of the whole thing.  It was the world's smallest cyclotron, but they had got fantastic  results. They had all kinds of  special techniques and tricks. If they wanted to  change something  in the "D's" &#8212;  the D-shaped half circles that  the particles go around &#8212; they'd take a screwdriver, and remove the D's by hand, fix  them, and put them back. At Princeton it was a lot harder, and at MIT you had  to take  a crane  that came rolling  across the ceiling, lower the hooks, and it was a hellllll of a job.)</p></blockquote>
<p>Princeton and Cornell had inferior equipment, but they got superior results partly because of the quick iteration loop, eliminating the step of waiting on the engineers to make changes. Scientists at these schools could very quickly try something, make adjustments, and try again, where at MIT the same adjustments took a lot of time.</p>
<p><a href="http://en.wikipedia.org/wiki/Shuji_Nakamura">Shuji Nakamura</a>, inventor of the blue LED, <a href="http://archive.sciencewatch.com/jan-feb2000/sw_jan-feb2000_page3.htm">said something similar about his work</a>:</p>
<blockquote><p>I had a very, very small budget and had to make everything I needed myself. I even made my own reactors—the furnaces needed to do the crystal work. </p></blockquote>
<p>Nakamura succeeded in creating a blue LED, working by himself, when huge multinationals were pouring hundreds of millions of dollars into R&amp;D without results. Elsewhere, he commented that the ability to make adjustments to his equipment quickly, without getting engineers involved, was one of the secrets to his success.</p>
<p>It struck me that this is one of the reasons why I get better results with Python than with compiled languages like C and C++. With Python, there's no compiler in the loop, so the iteration cycle is very fast &#8212; rarely more than 10 seconds to run all the unit tests.</p>
<p>This affects every part of the development cycle. Development itself is a lot faster, so you get more done. With a faster cycle, refactoring code in small steps is also quick and painless, so it's easier to evolve code. The cost of trying out new ideas is low, so you're encouraged to prototype lots of designs to get the best ones.</p>
<p>I think that in just about any kind of creative endeavor, the ability to rapidly iterate between creation and feedback gives a tremendous boost to productivity. This is one of the reasons why I'm so much more productive with Python.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/06/07/on-rapid-iteration/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>mailer version 0.5 released</title>
		<link>http://ginstrom.com/scribbles/2009/05/28/mailer-version-05-released/</link>
		<comments>http://ginstrom.com/scribbles/2009/05/28/mailer-version-05-released/#comments</comments>
		<pubDate>Thu, 28 May 2009 01:02:05 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[mailer]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1094</guid>
		<description><![CDATA[I've released version 0.5 of my mailer python module for sending emails. Thanks to a patch from Douglas Mayle, this version makes it possible to send HTML emails with attachments (previous versions only let you do one or the other).

Project homepage
pypi page

]]></description>
			<content:encoded><![CDATA[<p>I've released version 0.5 of my <a href="http://pypi.python.org/pypi/mailer/">mailer python module</a> for sending emails. Thanks to a patch from Douglas Mayle, this version makes it possible to send HTML emails with attachments (previous versions only let you do one or the other).</p>
<ul>
<li><a href="/code/mailer.html">Project homepage</a></li>
<li><a href="http://pypi.python.org/pypi/mailer/">pypi page</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/05/28/mailer-version-05-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converting kanji numbers to integers with Python</title>
		<link>http://ginstrom.com/scribbles/2009/04/28/converting-kanji-numbers-to-integers-with-python/</link>
		<comments>http://ginstrom.com/scribbles/2009/04/28/converting-kanji-numbers-to-integers-with-python/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 05:19:25 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[conversion]]></category>
		<category><![CDATA[kanji]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1008</guid>
		<description><![CDATA[A question on StackOverflow about converting kanji numbers (e.g. "五十五") into integers in C++ got me interested in solving this using Python.
The result is my kanjinums module, with a function kanji2num that will convert a string containing a kanji num to a Python integer.
Download the source distribution (kanjinums-0.1.zip)
Download the Windows installer (kanjinums-0.1.win32.exe)
Download the unit tests [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://stackoverflow.com/questions/795868/how-to-parse-kanji-numeric-characters-using-icu" rel="nofollow">question on StackOverflow</a> about converting kanji numbers (e.g. "五十五") into integers in C++ got me interested in solving this using Python.</p>
<p>The result is my kanjinums module, with a function kanji2num that will convert a string containing a kanji num to a Python integer.</p>
<p><a href="/code/kanjinums-0.1.zip">Download the source distribution (kanjinums-0.1.zip)</a><br />
<a href="/code/kanjinums-0.1.win32.exe">Download the Windows installer (kanjinums-0.1.win32.exe)</a><br />
<a href="/code/test_kanjinums.zip">Download the unit tests (test_kanjinums.zip)</a></p>
<p>Examples:</p>
<div class="dean_ch" style="white-space: wrap;">
&gt;&gt;&gt; <span class="kw1">import</span> kanjinums<br />
&gt;&gt;&gt; kanjinums.<span class="me1">kanji2num</span><span class="br0">&#40;</span><span class="st0">&quot;五百十一&quot;</span>, <span class="st0">&quot;sjis&quot;</span><span class="br0">&#41;</span><br />
<span class="nu0">511</span><br />
&gt;&gt;&gt; kanjinums.<span class="me1">kanji2num</span><span class="br0">&#40;</span><span class="st0">&quot;三万十五&quot;</span>, <span class="st0">&quot;sjis&quot;</span><span class="br0">&#41;</span><br />
<span class="nu0">30015</span></div>
<p>Here's the full code:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="co1">#coding: UTF8</span><br />
<span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
Converts kanji numbers into integers</p>
<p>Can covert numbers up to 9,999,999,999,999,999<br />
(九千九百九十九兆九千九百九十九億九千九百九十九万九千九百九十九)</p>
<p>Released under MIT license.<br />
&quot;</span><span class="st0">&quot;&quot;</span><br />
__version__ = <span class="st0">&quot;0.1&quot;</span><br />
__author__ &nbsp;= <span class="st0">&quot;Ryan Ginstrom&quot;</span><br />
__license__ = <span class="st0">&quot;MIT&quot;</span><br />
__description__ = <span class="st0">&quot;A module to convert kanji numbers into Python integers&quot;</span></p>
<p>NUMS = <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="nu0">1</span>, u<span class="st0">&quot;一&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">2</span>, u<span class="st0">&quot;二&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">3</span>, u<span class="st0">&quot;三&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">4</span>, u<span class="st0">&quot;四&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">5</span>, u<span class="st0">&quot;五&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">6</span>, u<span class="st0">&quot;六&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">7</span>, u<span class="st0">&quot;七&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">8</span>, u<span class="st0">&quot;八&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">9</span>, u<span class="st0">&quot;九&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">10</span>, u<span class="st0">&quot;十&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">100</span>, u<span class="st0">&quot;百&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">1000</span>, u<span class="st0">&quot;千&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">10000</span>, u<span class="st0">&quot;万&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">100000000</span>, u<span class="st0">&quot;億&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">1000000000000</span>, u<span class="st0">&quot;兆&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>KANJIS = <span class="kw2">dict</span><span class="br0">&#40;</span><span class="br0">&#40;</span>kanji, num<span class="br0">&#41;</span> <span class="kw1">for</span> <span class="br0">&#40;</span>num, kanji<span class="br0">&#41;</span> <span class="kw1">in</span> NUMS<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> _break_down_nums<span class="br0">&#40;</span>nums<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; first, second, third, rest = nums<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">3</span>:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> first &lt; third <span class="kw1">or</span> third &lt; second:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#91;</span>first+second, third<span class="br0">&#93;</span> + rest<br />
&nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#91;</span>first, second*third<span class="br0">&#93;</span> + rest</p>
<p><span class="kw1">def</span> kanji2num<span class="br0">&#40;</span>kanji, enc=<span class="st0">&quot;utf-8&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Convert the kanji number to a Python integer.<br />
&nbsp; &nbsp; Supply `kanji` as a unicode string, or a byte string<br />
&nbsp; &nbsp; with the encoding specified in `enc`.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">isinstance</span><span class="br0">&#40;</span>kanji, <span class="kw2">unicode</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; kanji = <span class="kw2">unicode</span><span class="br0">&#40;</span>kanji, enc<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># get the string as list of numbers</span><br />
&nbsp; &nbsp; nums = <span class="br0">&#91;</span>KANJIS<span class="br0">&#91;</span>x<span class="br0">&#93;</span> <span class="kw1">for</span> x <span class="kw1">in</span> kanji<span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; num = <span class="nu0">0</span><br />
&nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">len</span><span class="br0">&#40;</span>nums<span class="br0">&#41;</span> &gt; <span class="nu0">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; first, second, rest = nums<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">2</span>:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> second &lt; first: <span class="co1"># e.g. [10, 3, ...]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> any<span class="br0">&#40;</span>x &gt; first <span class="kw1">for</span> x <span class="kw1">in</span> rest<span class="br0">&#41;</span>: <span class="co1"># e.g. [500, 3, 10000, ...]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nums = _break_down_nums<span class="br0">&#40;</span>nums<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>: <span class="co1"># e.g. [500, 3, 10, ...]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num += first<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nums = <span class="br0">&#91;</span>second<span class="br0">&#93;</span> + rest<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>: <span class="co1"># e.g. [3, 10, ...]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nums = <span class="br0">&#91;</span>first*second<span class="br0">&#93;</span> + rest</p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> num + <span class="kw2">sum</span><span class="br0">&#40;</span>nums<span class="br0">&#41;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/04/28/converting-kanji-numbers-to-integers-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inno Setup: Determining the data directory at install time</title>
		<link>http://ginstrom.com/scribbles/2009/04/08/inno-setup-determining-the-data-directory-at-install-time/</link>
		<comments>http://ginstrom.com/scribbles/2009/04/08/inno-setup-determining-the-data-directory-at-install-time/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 12:28:14 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[app data]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[compiler]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[inno]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=961</guid>
		<description><![CDATA[Inno Setup is a fantastic and free application for creating Windows setup programs. It takes so much of the hassle out of the process that it's almost fun.
I recently needed to extend Inno Setup with a custom code section: I needed to install the program's data to the Common App Data folder or the Local [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jrsoftware.org/isinfo.php">Inno Setup</a> is a fantastic and free application for creating Windows setup programs. It takes so much of the hassle out of the process that it's <em>almost</em> fun.</p>
<p>I recently needed to extend Inno Setup with a custom code section: I needed to install the program's data to the Common App Data folder or the Local App Data folder, depending on a selection made during the installation process (install for all users, or just me). Here's the script I came up with:</p>
<div class="dean_ch" style="white-space: wrap;">
; AppDataTest.<span class="me1">iss</span><br />
<span class="br0">&#91;</span><span class="kw1">Setup</span><span class="br0">&#93;</span><br />
<span class="kw3">AppName</span>=AppData Test<br />
<span class="kw3">AppVerName</span>=AppData Test <span class="nu0">0.1</span><br />
<span class="kw3">DefaultDirName</span>=<span class="br0">&#123;</span><span class="kw1">pf</span><span class="br0">&#125;</span>\AppDataTest<br />
<span class="kw3">DefaultGroupName</span>=AppDataTest<br />
<span class="kw3">OutputDir</span>=<span class="kw1">Setup</span></p>
<p><span class="br0">&#91;</span><span class="kw1">Files</span><span class="br0">&#93;</span><br />
<span class="kw3">Source</span>: AppDataTest.<span class="me1">iss</span>; &nbsp;<span class="kw3">DestDir</span>: <span class="br0">&#123;</span><span class="kw1">app</span><span class="br0">&#125;</span>\;<br />
<span class="kw3">Source</span>: AppDataTest.<span class="me1">iss</span>; &nbsp;<span class="kw3">DestDir</span>: <span class="br0">&#123;</span>code:DefAppDataFolder<span class="br0">&#125;</span>\Test\;</p>
<p><span class="br0">&#91;</span><span class="kw1">Tasks</span><span class="br0">&#93;</span><br />
<span class="kw3">Name</span>: common; <span class="kw3">Description</span>: <span class="st0">&quot;&amp;All users&quot;</span>; <span class="kw3">GroupDescription</span>: <span class="st0">&quot;Install For:&quot;</span>; <span class="kw3">Flags</span>: <span class="kw2">exclusive</span> <span class="kw2">unchecked</span><br />
<span class="kw3">Name</span>: local; &nbsp;<span class="kw3">Description</span>: <span class="st0">&quot;Just &amp;me&quot;</span>; <span class="kw3">GroupDescription</span>: <span class="st0">&quot;Install For:&quot;</span>; <span class="kw3">Flags</span>: <span class="kw2">exclusive</span></p>
<p><span class="br0">&#91;</span><span class="kw1">Icons</span><span class="br0">&#93;</span><br />
<span class="kw3">Name</span>: <span class="br0">&#123;</span><span class="kw1">group</span><span class="br0">&#125;</span>\Uninstall AppDataTest; <span class="kw3">Filename</span>: <span class="br0">&#123;</span>uninstallexe<span class="br0">&#125;</span></p>
<p><span class="br0">&#91;</span>Code<span class="br0">&#93;</span><br />
<span class="kw2">function</span> DefAppDataFolder<span class="br0">&#40;</span>Param: <span class="kw4">String</span><span class="br0">&#41;</span>: <span class="kw4">String</span>;<br />
<span class="kw2">begin</span><br />
&nbsp; <span class="kw2">if</span> IsTaskSelected<span class="br0">&#40;</span><span class="st0">'common'</span><span class="br0">&#41;</span> <span class="kw2">then</span><br />
&nbsp; &nbsp; Result := ExpandConstant<span class="br0">&#40;</span><span class="st0">'{commonappdata}'</span><span class="br0">&#41;</span><br />
&nbsp; <span class="kw2">else</span><br />
&nbsp; &nbsp; Result := ExpandConstant<span class="br0">&#40;</span><span class="st0">'{localappdata}'</span><span class="br0">&#41;</span><br />
<span class="kw2">end</span>;</div>
<p>I created a radio button for the [Tasks] page, asking whether the user wants to install the application for all users, or just herself.</p>
<p>Then in the [Code] section, I created a function to expand "DefAppDataFolder" to <code>commonappdata</code> or <code>localappdata</code>, depending on whether "common" or "local" is selected in in the [Tasks] section (<code>IsTaskSelected('common')</code>).</p>
<p>This value is then expanded in the [Files] section, at this line:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw3">Source</span>: AppDataTest.<span class="me1">iss</span>; &nbsp;<span class="kw3">DestDir</span>: <span class="br0">&#123;</span>code:DefAppDataFolder<span class="br0">&#125;</span>\Test\;</div>
<p>Here's the <a href="/code/AppDataTest/AppDataTest.iss" title="AppDataTest.iss">setup script (AppDataTest.iss)</a>, and the resulting <a href="/code/AppDataTest/setup.exe" title="setup.exe">setup program (setup.exe)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/04/08/inno-setup-determining-the-data-directory-at-install-time/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Version 0.2 of mailer module released</title>
		<link>http://ginstrom.com/scribbles/2009/03/29/version-02-of-mailer-module-released/</link>
		<comments>http://ginstrom.com/scribbles/2009/03/29/version-02-of-mailer-module-released/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 02:45:19 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[mailer]]></category>
		<category><![CDATA[module]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=927</guid>
		<description><![CDATA[I updated my mailer module (blogged about here) to version 0.2, and also uploaded it to pyPI.
Improvements in this version:

Default arguments in Message.__init__() method
Support for non-ascii charsets (in body and subject)
Support for Python 2.4

With the support for non-ascii encodings, you can now do this:

from mailer import Mailer
from mailer import Message
mailer = Mailer&#40;'smtp.example.com'&#41;
msg = Message&#40;From=&#34;me@example.com&#34;, To=&#34;you@example.com&#34;&#41;
msg.Subject [...]]]></description>
			<content:encoded><![CDATA[<p>I updated my mailer module (<a href="/scribbles/2009/03/15/a-module-to-send-email-simply-in-python/">blogged about here</a>) to version 0.2, and also uploaded it to <a href="http://pypi.python.org/pypi/mailer/">pyPI</a>.</p>
<p>Improvements in this version:</p>
<ul>
<li>Default arguments in Message.__init__() method</li>
<li>Support for non-ascii charsets (in body and subject)</li>
<li>Support for Python 2.4</li>
</ul>
<p>With the support for non-ascii encodings, you can now do this:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> mailer <span class="kw1">import</span> Mailer<br />
<span class="kw1">from</span> mailer <span class="kw1">import</span> Message</p>
<p>mailer = Mailer<span class="br0">&#40;</span><span class="st0">'smtp.example.com'</span><span class="br0">&#41;</span></p>
<p>msg = Message<span class="br0">&#40;</span>From=<span class="st0">&quot;me@example.com&quot;</span>, To=<span class="st0">&quot;you@example.com&quot;</span><span class="br0">&#41;</span><br />
msg.<span class="me1">Subject</span> = <span class="st0">&quot;テキストメール&quot;</span><br />
msg.<span class="me1">Body</span> = <span class="st0">&quot;これは、日本語のキストメールでございます。&quot;</span><br />
msg.<span class="me1">charset</span> = <span class="st0">&quot;utf-8&quot;</span></p>
<p>mailer.<span class="me1">send</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span></div>
<p>And the Message instance will properly encode the subject line and message body. Note that there's currently no support for Unicode strings; you've got to pass in encoded strings.</p>
<p>Thanks to everyone who provided feedback on this module.</p>
<p>The mailer module also has a <a href="/code/mailer.html">home page</a>.</p>
<p>The full code of the new module is below.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="co1">#coding: UTF8</span><br />
<span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
mailer module</p>
<p>Simple front end to the smtplib and email modules,<br />
to simplify sending email.</p>
<p>A lot of this code was taken from the online examples in the<br />
email module documentation:<br />
http://docs.python.org/library/email-examples.html</p>
<p>Released under MIT license.</p>
<p>Sample code:</p>
<p>import mailer</p>
<p>message = mailer.Message()<br />
message.From = &quot;</span>me@example.<span class="me1">com</span><span class="st0">&quot;<br />
message.To = &quot;</span>you@example.<span class="me1">com</span><span class="st0">&quot;<br />
message.Subject = &quot;</span>My Vacation<span class="st0">&quot;<br />
message.Body = open(&quot;</span>letter.<span class="me1">txt</span><span class="st0">&quot;, &quot;</span>rb<span class="st0">&quot;).read()<br />
message.attach(&quot;</span>picture.<span class="me1">jpg</span><span class="st0">&quot;)</p>
<p>mailer = mailer.Mailer('mail.example.com')<br />
mailer.send(message)</p>
<p>&quot;</span><span class="st0">&quot;&quot;</span><br />
<span class="kw1">import</span> <span class="kw3">smtplib</span></p>
<p><span class="co1"># this is to support name changes</span><br />
<span class="co1"># from version 2.4 to version 2.5</span><br />
<span class="kw1">try</span>:<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span> <span class="kw1">import</span> encoders<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">header</span> <span class="kw1">import</span> make_header<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">message</span> <span class="kw1">import</span> Message<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">audio</span> <span class="kw1">import</span> MIMEAudio<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">base</span> <span class="kw1">import</span> MIMEBase<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">image</span> <span class="kw1">import</span> MIMEImage<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">multipart</span> <span class="kw1">import</span> MIMEMultipart<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">text</span> <span class="kw1">import</span> MIMEText<br />
<span class="kw1">except</span> <span class="kw2">ImportError</span>:<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span> <span class="kw1">import</span> Encoders as encoders<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">Header</span> <span class="kw1">import</span> make_header<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEMessage</span> <span class="kw1">import</span> Message<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEAudio</span> <span class="kw1">import</span> MIMEAudio<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEBase</span> <span class="kw1">import</span> MIMEBase<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEImage</span> <span class="kw1">import</span> MIMEImage<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEMultipart</span> <span class="kw1">import</span> MIMEMultipart<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEText</span> <span class="kw1">import</span> MIMEText</p>
<p><span class="co1"># For guessing MIME type based on file name extension</span><br />
<span class="kw1">import</span> <span class="kw3">mimetypes</span></p>
<p><span class="kw1">from</span> <span class="kw3">os</span> <span class="kw1">import</span> path</p>
<p>__version__ = <span class="st0">&quot;0.2&quot;</span><br />
__author__ = <span class="st0">&quot;Ryan Ginstrom&quot;</span><br />
__license__ = <span class="st0">&quot;MIT&quot;</span><br />
__description__ = <span class="st0">&quot;A module to send email simply in Python&quot;</span></p>
<p><span class="kw1">class</span> Mailer<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Represents an SMTP connection.</p>
<p>&nbsp; &nbsp; Use login() to log in with a username and password.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, host=<span class="st0">&quot;localhost&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">host</span> = host<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._usr = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pwd = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> login<span class="br0">&#40;</span><span class="kw2">self</span>, usr, <span class="kw3">pwd</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._usr = usr<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pwd = <span class="kw3">pwd</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> send<span class="br0">&#40;</span><span class="kw2">self</span>, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Send one message or a sequence of messages.</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; Every time you call send, the mailer creates a new<br />
&nbsp; &nbsp; &nbsp; &nbsp; connection, so if you have several emails to send, pass<br />
&nbsp; &nbsp; &nbsp; &nbsp; them as a list:<br />
&nbsp; &nbsp; &nbsp; &nbsp; mailer.send([msg1, msg2, msg3])<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server = <span class="kw3">smtplib</span>.<span class="me1">SMTP</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">host</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>._usr <span class="kw1">and</span> <span class="kw2">self</span>._pwd:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">login</span><span class="br0">&#40;</span><span class="kw2">self</span>._usr, <span class="kw2">self</span>._pwd<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num_msgs = <span class="kw2">len</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> m <span class="kw1">in</span> msg:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._send<span class="br0">&#40;</span>server, m<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">TypeError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._send<span class="br0">&#40;</span>server, msg<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">quit</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _send<span class="br0">&#40;</span><span class="kw2">self</span>, server, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Sends a single message using the server<br />
&nbsp; &nbsp; &nbsp; &nbsp; we created in send()<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; me = msg.<span class="me1">From</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; you = <span class="br0">&#91;</span>x.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">for</span> x <span class="kw1">in</span> msg.<span class="me1">To</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">sendmail</span><span class="br0">&#40;</span>me, you, msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">class</span> Message<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Represents an email message.</p>
<p>&nbsp; &nbsp; Set the To, From, Subject, and Body attributes as<br />
&nbsp; &nbsp; plain-text strings. Optionally, set the Html attribute<br />
&nbsp; &nbsp; to send an HTML email, or use the attach() method<br />
&nbsp; &nbsp; to attach files.</p>
<p>&nbsp; &nbsp; Use the charset property to send messages using other<br />
&nbsp; &nbsp; than us-ascii</p>
<p>&nbsp; &nbsp; If you specify an attachments argument, it should be a<br />
&nbsp; &nbsp; list of attachment filenames: [&quot;</span>file1.<span class="me1">txt</span><span class="st0">&quot;, &quot;</span>file2.<span class="me1">txt</span><span class="st0">&quot;]</p>
<p>&nbsp; &nbsp; Send using the Mailer class.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, To=<span class="kw2">None</span>, From=<span class="kw2">None</span>, Subject=<span class="kw2">None</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Body=<span class="kw2">None</span>, Html=<span class="kw2">None</span>, attachments=<span class="kw2">None</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; charset=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">attachments</span> = attachments <span class="kw1">or</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._to = To<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">From</span> = From<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Subject</span> = Subject<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Body</span> = Body<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Html</span> = Html<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">charset</span> = charset <span class="kw1">or</span> <span class="st0">'us-ascii'</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _get_to<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Making this a property so we can be permissive about<br />
&nbsp; &nbsp; &nbsp; &nbsp; how to set the &quot;</span>To<span class="st0">&quot; field, i.e.<br />
&nbsp; &nbsp; &nbsp; &nbsp; me;you/me,you/me; you/me, you<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; addrs = <span class="kw2">self</span>._to.<span class="me1">replace</span><span class="br0">&#40;</span><span class="st0">&quot;;&quot;</span>, <span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;, &quot;</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="br0">&#91;</span>x.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> x <span class="kw1">in</span> addrs<span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> _set_to<span class="br0">&#40;</span><span class="kw2">self</span>, to<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._to = to</p>
<p>&nbsp; &nbsp; To = <span class="kw2">property</span><span class="br0">&#40;</span>_get_to, _set_to,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doc=<span class="st0">&quot;&quot;</span><span class="st0">&quot;The recipient(s) of the email.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Separate multiple recipients with<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; commas or semicolons&quot;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> as_string<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Get the email as a string to send in the mailer&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">attachments</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._plaintext<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._multipart<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _plaintext<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Plain text email with no attachments&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">Html</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg &nbsp;= <span class="kw2">self</span>._with_html<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._set_info<span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _with_html<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;There's an html part&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; outer = MIMEMultipart<span class="br0">&#40;</span><span class="st0">'alternative'</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; part1 = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; part2 = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Html</span>, <span class="st0">'html'</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>part1<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>part2<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> outer</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _set_info<span class="br0">&#40;</span><span class="kw2">self</span>, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">charset</span> == <span class="st0">'us-ascii'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'Subject'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">Subject</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; subject = <span class="kw2">unicode</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Subject</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'Subject'</span><span class="br0">&#93;</span> = <span class="kw2">str</span><span class="br0">&#40;</span>make_header<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span>subject,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'From'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">From</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'To'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">To</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _multipart<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;The email has attachments&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEMultipart<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">attach</span><span class="br0">&#40;</span>MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._set_info<span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">preamble</span> = <span class="kw2">self</span>.<span class="me1">Subject</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> filename <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">attachments</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._add_attachment<span class="br0">&#40;</span>msg, filename<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _add_attachment<span class="br0">&#40;</span><span class="kw2">self</span>, outer, filename<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; ctype, encoding = <span class="kw3">mimetypes</span>.<span class="me1">guess_type</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ctype <span class="kw1">is</span> <span class="kw2">None</span> <span class="kw1">or</span> encoding <span class="kw1">is</span> <span class="kw1">not</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># No guess could be made, or the file is encoded</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># (compressed), so use a generic bag-of-bits type.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctype = <span class="st0">'application/octet-stream'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; maintype, subtype = ctype.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">'/'</span>, <span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fp = <span class="kw2">open</span><span class="br0">&#40;</span>filename, <span class="st0">'rb'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> maintype == <span class="st0">'text'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Note: we should handle calculating the charset</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEText<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> maintype == <span class="st0">'image'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEImage<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> maintype == <span class="st0">'audio'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEAudio<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEBase<span class="br0">&#40;</span>maintype, subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">set_payload</span><span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Encode the payload using Base64</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; encoders.<span class="me1">encode_base64</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fp.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Set the filename parameter</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">add_header</span><span class="br0">&#40;</span><span class="st0">'Content-Disposition'</span>, <span class="st0">'attachment'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; filename=path.<span class="me1">basename</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> attach<span class="br0">&#40;</span><span class="kw2">self</span>, filename<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Attach a file to the email. Specify the name of<br />
&nbsp; &nbsp; &nbsp; &nbsp; the file; Message will figure out the MIME type<br />
&nbsp; &nbsp; &nbsp; &nbsp; and load the file.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">attachments</span>.<span class="me1">append</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/03/29/version-02-of-mailer-module-released/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>The Adapter Pattern in Python</title>
		<link>http://ginstrom.com/scribbles/2009/03/27/the-adapter-pattern-in-python/</link>
		<comments>http://ginstrom.com/scribbles/2009/03/27/the-adapter-pattern-in-python/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 03:36:57 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[adapter]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[GoF]]></category>
		<category><![CDATA[pattern]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=922</guid>
		<description><![CDATA[Interface mismatches are one of the banes of code reuse. You want to integrate component A and component B into your program, but component A expects a method called half_empty() while component B only has a method called half_full(). The Gang of Four (GoF) Adapter pattern is used to convert the interface of an object [...]]]></description>
			<content:encoded><![CDATA[<p>Interface mismatches are one of the banes of code reuse. You want to integrate component A and component B into your program, but component A expects a method called half_empty() while component B only has a method called half_full(). The <a href="http://en.wikipedia.org/wiki/Gang_of_Four_(software)">Gang of Four (GoF)</a> Adapter pattern is used to convert the interface of an object to one the client expects, allowing collaboration between classes that normally couldn't work together due to differing interfaces.</p>
<h3>2D Land: A Demonstration of the Adapter Pattern</h3>
<p>Let's motivate that with a little example. We're going to start with a simple system, then add components to it with an interface that's different from the one our system expects. We'll use the Adapter pattern to wrap the new components, so we can use them without changing the code in our existing system.</p>
<p>So let's get started. We've been tasked with writing the back-end code for 2D Land, a cutting-edge world simulation program involving poorly drawn cartoon figures. Our initial spec is pretty simple: our world consists of people, and when a person is clicked, their name and a speech bubble is printed. We need to code a Person class, and a click_creature() function that will return a person's name and speech bubble to the GUI team.</p>
<p><img src="/img/adapter01.png" alt="2D Land version 1.0" /></p>
<p>So let's get coding. One way to code this would be as shown below. We have a Person class, with a name property and a make_noise() method. These can be accessed to retrieve the Person's name and speech bubble.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> Person<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a person in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name<br />
&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;hello&quot;</span></p>
<p><span class="kw1">def</span> click_creature<span class="br0">&#40;</span>creature<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; React to a click by retrieving the creature's<br />
&nbsp; &nbsp; name and what is says<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> creature.<span class="me1">name</span>, creature.<span class="me1">make_noise</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>The Person class takes a name argument, which it stores in its name attribute. The click_creature() function retrieves the person's name and speech-bubble text. We test it, and everything works as expected. Looks like it's time for a launch party!</p>
<h3>More Features in 2D Land</h3>
<p>After we get back from our team trip to Cancun, we find that our users are so happy with 2D Land that management has decided to build 2D Land version 2.0! The killer new feature of version 2.0 is that in addition to people, 2D Land will now also have dogs.</p>
<p><img src="/img/adapter02.png" alt="2D Land version 2.0" /></p>
<p>Luckily, the programmers over in the Pet Land team are going to let us use their Dog class. The Dog class has a name property, and a bark() method that returns the dog's bark sound.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> Dog<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a dog in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name<br />
&nbsp; &nbsp; <span class="kw1">def</span> bark<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;woof&quot;</span></div>
<p>As it stands, the Dog class doesn't have the interface that our clients expect. It has a name property, but instead of a make_noise() method, it's got a bark() method. But we can use the Adapter pattern to wrap the Dog class and give it the expected interface.</p>
<p>Let's start by solving this the classic GoF way. There are actually two ways to implement Adapter in GoF: the Class Adapter and the Object Adapter. The Class Adapter uses multiple inheritance, while the Object Adapter uses encapsulation. For the sake of completeness I'm going to show both of them, and then explain why the Object Adapter is almost always the best choice for Python.</p>
<p>According to the classic implementation of the Adapter pattern, we need a common class that Person and a dog adapter can inherit from; let's call it a Creature class. The DogClassAdapter and DogObjectAdapter classes will each inherit from Creature; DogClassAdapter will then inherit from Dog, and DogObjectAdapter will wrap Dog.</p>
<p>According to the pattern, Creature is supposed to be an abstract base class (ABC); that is, it's not supposed to be instantiated directly. Python 2.X doesn't have ABCs as a language feature, but we can fake it here by having calls to make_noise() raise a NotImplementedError. This means that we need classes to inherit from Creature and implement make_noise() for us.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> dog <span class="kw1">import</span> Dog</p>
<p><span class="kw1">class</span> Creature<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;The base class for creatures in 2D Land&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; This is a technique to fake an ABC<br />
&nbsp; &nbsp; &nbsp; &nbsp; in Python 2.X<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">raise</span> <span class="kw2">NotImplementedError</span></p>
<p><span class="kw1">class</span> Person<span class="br0">&#40;</span>Creature<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a person in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;hello&quot;</span></p>
<p><span class="kw1">class</span> DogClassAdapter<span class="br0">&#40;</span>Creature, Dog<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Adapts the Dog class through multiple inheritance&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; Dog.<span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Provide the 'make_noise' method that<br />
&nbsp; &nbsp; &nbsp; &nbsp; the client expects<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">bark</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>DogClassAdapter inherits from Creature and Dog, getting the functionality of both. It takes a name parameter in its __init__() method, which it passes on to Dog. It then implements a make_noise() method, returning the results of the bark() method it inherited from Dog.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> DogObjectAdapter<span class="br0">&#40;</span>Creature<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Adapts the Dog class through encapsulation&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, canine<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">canine</span> = canine</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;This is the only method that's adapted&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">canine</span>.<span class="me1">bark</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__getattr__</span><span class="br0">&#40;</span><span class="kw2">self</span>, attr<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Everything else is delegated to the object&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">getattr</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">canine</span>, attr<span class="br0">&#41;</span></div>
<p>DogObjectAdapter only inherits from Creature. It takes a Dog instance as a parameter to its __init__() method, and stores that instance as self.canine. It implements a make_noise() method, which returns the result of calling the bark() method of its wrapped Dog object. All other calls on the class are passed to its canine instance via the __getattr__() method.</p>
<p>In both cases, we only need to implement the interface we're adapting. DogClassAdapter inherits the rest of the Dog interface, while DogObjectAdapter uses __getattr__() to provide the same interface as the Dog class, with the exception of the methods it implements itself.</p>
<p>And here's why we don't need the Class Adapter. Class Adapter is basically a shortcut to avoid coding stubs. In languages like C++, Object Adapter would force us to implement stubs for every method on the Dog class, just so we could pass them on to the wrapped Dog instance. With Class Adapter, however, we'd already have the behaviour implemented, so wouldn't need to write stubs. This doesn't make any difference in a simple class like Dog, but consider a huge class like StringIO.StringIO from the standard library; writing stubs for every method in that class just to adapt the interface slightly would be a real pain. But in Python, we don't have to write stubs for the behaviour we don't wrap; we can take advantage of dynamic dispatching instead, by implementing the __getattr__() method.</p>
<blockquote><p>__getattr__() is a "magic" method, as denoted by the double underscores. The Python interpreter calls it when it does an attribute lookup on the object, and can't find a matching attribute. By intercepting this call and passing on the attribute lookup to the wrapped object, DogObjectAdapter only needs to implement the make_noise() method; everything else gets passed on to its wrapped object.</p></blockquote>
<h3>Flattening the Object Hierarchy</h3>
<p>The code above works; we can created adapted dogs, and feed them into our click_creature() function. But is inheriting from a Creature base class the best way? With statically typed languages, inheritance is used for two purposes: to coerce types, and to inherit behaviour. By coercing types, I mean using a common base class so that we can feed a common type to the click_creature() function. These are the kinds of hoops you need to jump through to make the compiler happy in statically typed languages. In Python, we don't need to use inheritance to coerce the type system, because we use duck typing; we only need to use inheritance for behaviour.</p>
<blockquote><p><strong>Duck typing</strong>: ask what an object can do, rather than ask what type an object is (i.e. don't ask if it's a duck; ask if it quacks like a duck).</p></blockquote>
<p>So we don't need to inherit from a Creature base class in order to use our various objects in the click_creature() function. And in fact, there's a big problem with this inheritance approach: it would force us to change our existing codebase, by modifying the Person class to inherit from Creature. So let's flatten the hierarchy out:</p>
<p><img src="/img/adapter03.png" alt="Flattening the inheritance hierarchy" /></p>
<p>Here's our code without the Creature base class, and getting rid of the Class Adapter:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> dog <span class="kw1">import</span> Dog</p>
<p><span class="kw1">class</span> Person<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a person in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;hello&quot;</span></p>
<p><span class="kw1">class</span> DogAdapter<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Adapts the Dog class through encapsulation&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, canine<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">canine</span> = canine</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;This is the only method that's adapted&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">canine</span>.<span class="me1">bark</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__getattr__</span><span class="br0">&#40;</span><span class="kw2">self</span>, attr<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Everything else is delegated to the object&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">getattr</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">canine</span>, attr<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> click_creature<span class="br0">&#40;</span>creature<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; React to a click by showing the creature's<br />
&nbsp; &nbsp; name and what is says<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>creature.<span class="me1">name</span>, creature.<span class="me1">make_noise</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
<p>This is a lot simpler. We've captured the intent of the Adapter pattern, without bothering with the trappings of less dynamic languages.</p>
<p>Just because the GoF implement a pattern in a certain way doesn't mean it's the only or even best way to do it in Python. Use the essence of the pattern, and leave out the accidents of implementation.</p>
<h3>Testing out the System</h3>
<p>Let's test out our DogAdapter class with a function that simulates clicks on each type of creature in 2D Land.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> dog <span class="kw1">import</span> Dog<br />
<span class="kw1">from</span> listing3 <span class="kw1">import</span> Person, DogAdapter</p>
<p><span class="kw1">def</span> exercise_system<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; person = Person<span class="br0">&#40;</span><span class="st0">&quot;Bob&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; canine = DogAdapter<span class="br0">&#40;</span>Dog<span class="br0">&#40;</span><span class="st0">&quot;Fido&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> critter <span class="kw1">in</span> <span class="br0">&#40;</span>person, canine<span class="br0">&#41;</span>:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> critter.<span class="me1">name</span>, <span class="st0">&quot;says&quot;</span>, critter.<span class="me1">make_noise</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; exercise_system<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>animate_objects() creates instances of classes Person and DogAdapter; it then prints the name and speech bubbles of each object. The output is shown below.</p>
<p>Output:</p>
<div class="dean_ch" style="white-space: wrap;">
Bob says hello<br />
Fido says woof</div>
<p>Perfect! Looks like we're ready to launch version 2.0.</p>
<h3>Extending the Adapter Concept</h3>
<p>We've got our Adapter working pretty well now, but we can still make it better. Think about how we added a Dog class to 2D Land. What if we later want to add a Cat class, and Bird class, and so on? Here's a Cat class, that has a name attribute, and a meow() method that returns the cat's meow sound.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> Cat<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a cat in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name<br />
&nbsp; &nbsp; <span class="kw1">def</span> meow<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;meow&quot;</span></div>
<p>The problem with the current implementation is that every time we add a new class to our system, we're potentially going to have to write a new adapter class for it.</p>
<p>We can take advantage of Python's dynamic nature to write a single, generic adapter class for all the new classes we add. Our generic adapter will take two arguments in its __init__() method: the object it's going to wrap, and an implementation of make_noise().</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> CreatureAdapter<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Adapts a creature for clients in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, creature, make_noise<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Pass in the function to use as 'make_noise'&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">creature</span> = creature<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">make_noise</span> = make_noise</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__getattr__</span><span class="br0">&#40;</span><span class="kw2">self</span>, attr<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Everything else is delegated to the object&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">getattr</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">creature</span>, attr<span class="br0">&#41;</span></div>
<p>Note that the code no longer has to know anything about the Dog class or other creatures in 2D land. All we need to do is supply an object to adapt and a method to use for make_noise(), and we're done.</p>
<p>So let's test out the new system, and see how we'd specify the make_noise() method.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> dog <span class="kw1">import</span> Dog<br />
<span class="kw1">from</span> cat <span class="kw1">import</span> Cat<br />
<span class="kw1">from</span> twodeeland <span class="kw1">import</span> Person, CreatureAdapter</p>
<p><span class="kw1">def</span> exercise_system<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; person = Person<span class="br0">&#40;</span><span class="st0">&quot;Bob&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; fido = Dog<span class="br0">&#40;</span><span class="st0">&quot;Fido&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; canine = CreatureAdapter<span class="br0">&#40;</span>fido, fido.<span class="me1">bark</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; whiskers = Cat<span class="br0">&#40;</span><span class="st0">&quot;Whiskers&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; feline = CreatureAdapter<span class="br0">&#40;</span>whiskers, whiskers.<span class="me1">meow</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> critter <span class="kw1">in</span> <span class="br0">&#40;</span>person, canine, feline<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> critter.<span class="me1">name</span>, <span class="st0">&quot;says&quot;</span>, critter.<span class="me1">make_noise</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>We have to specify which method to use as the make_noise() method on instance creation, but in return we no longer have to create an Adapter for each new class in the system. I'd say that's a big win.</p>
<p>Output:</p>
<div class="dean_ch" style="white-space: wrap;">
Bob says hello<br />
Fido says woof<br />
Whiskers says meow</div>
<p>One final note about this system: you may have been wondering what happens if the class we're adapting doesn't have a name attribute (for example, if the attribute is called "nickname"). In that case, we could simply create new class that inherits from the creature class, implementing the name attribute via a property, and pass an instance of that to our CreatureAdapter class.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> NicknameCat<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a cat in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, nickname<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">nickname</span> = nickname<br />
&nbsp; &nbsp; <span class="kw1">def</span> meow<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;meow&quot;</span></p>
<p><span class="kw1">class</span> NicknameCatAdapter<span class="br0">&#40;</span>NicknameCat<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; NicknameCat.<span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> _get_name<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">nickname</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> _set_name<span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">nickname</span> = name<br />
&nbsp; &nbsp; name = <span class="kw2">property</span><span class="br0">&#40;</span>_get_name, _set_name<span class="br0">&#41;</span></div>
<p>We could then do something like this:</p>
<div class="dean_ch" style="white-space: wrap;">
kitty = NicknameCatAdapter<span class="br0">&#40;</span><span class="st0">&quot;Whiskers&quot;</span><span class="br0">&#41;</span><br />
critter = CreatureAdapter<span class="br0">&#40;</span>kitty, kitty.<span class="me1">meow</span><span class="br0">&#41;</span></div>
<p>Note that this presupposes that the adapted class has some functionality that serves as the name attribute; the Adapter class is all about changing the interface of an object, not adding to its functionality.</p>
<h3>Using Adapter with Objects Other Than Classes</h3>
<p>The Adapter pattern as classically implemented works with classes, but that's just an accident of the languages that the pattern was initially made for. Essentially any object in Python is ripe for adapting. For example, you could adapt a function so that its signature was something that the client expected.</p>
<p>As an example, below we have a countdown() function. It takes as its arguments a number to count down from, and a callback function to call when it's done (callbacks are a common programming technique in things like multithreaded and asynchronous programs). We want to use the completed() function as its callback, but completed() takes an argument (the source), while countdown() calls its callback without any arguments. We can use the adapter pattern to change the signature of completed() to what countdown() expects.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> completed<span class="br0">&#40;</span>source<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">print</span> source, <span class="st0">&quot;completed&quot;</span></p>
<p><span class="kw1">def</span> countdown<span class="br0">&#40;</span>num, callback<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span>num, <span class="nu0">0</span>, <span class="nu0">-1</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;%s&#8230;&quot;</span> % i<br />
&nbsp; &nbsp; callback<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">def</span> nullarg_callback<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; completed<span class="br0">&#40;</span><span class="st0">&quot;countdown&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; countdown<span class="br0">&#40;</span><span class="nu0">3</span>, nullarg_callback<span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; main<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>Above, we adapted the completed() function using the nullarg_callback() function.</p>
<p>Output:</p>
<div class="dean_ch" style="white-space: wrap;">
3&#8230;<br />
2&#8230;<br />
1&#8230;<br />
countdown completed</div>
<p>The Adapter pattern changes the interface of an object in order to match the interface that's expected. In the 2D Land example, we adapted the Dog class to provide make_noise() method that our system expects. The Adapter pattern is a good choice any time you're integrating some code into an existing system, and the code has the needed functionality, but not the needed interface.</p>
<p><a href="/code/adapter_pattern.zip">Here's the code for this post</a>, together with unit tests.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/03/27/the-adapter-pattern-in-python/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A module to send email simply in Python</title>
		<link>http://ginstrom.com/scribbles/2009/03/15/a-module-to-send-email-simply-in-python/</link>
		<comments>http://ginstrom.com/scribbles/2009/03/15/a-module-to-send-email-simply-in-python/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 09:14:13 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[smtp]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=898</guid>
		<description><![CDATA[Update: I've released version 0.3 of the mailer module. See the mailer home page for details and the latest version.
The email and smtplib modules in Python are very powerful, but they're also a bit complex when you just want to send an email.
I wrote the mailer module as a front end to these two modules, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update</strong>: I've released version 0.3 of the mailer module. See the <a href="/code/mailer.html">mailer home page</a> for details and the latest version.</p>
<p>The <a href="http://docs.python.org/library/email.html">email</a> and <a href="http://docs.python.org/library/smtplib.html">smtplib</a> modules in Python are very powerful, but they're also a bit complex when you just want to send an email.</p>
<p>I wrote the <a href="/code/mailer_0.1.zip">mailer module</a> as a front end to these two modules, in order to make the task of sending email in Python using SMTP as simple as possible.</p>
<p>Below are some examples.</p>
<h3>Send a simple plain text email</h3>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">import</span> mailer</p>
<p>message = mailer.<span class="me1">Message</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">From</span> = <span class="st0">&quot;me@example.com&quot;</span><br />
message.<span class="me1">To</span> = <span class="st0">&quot;you@example.com&quot;</span><br />
message.<span class="me1">Subject</span> = <span class="st0">&quot;My Vacation&quot;</span><br />
message.<span class="me1">Body</span> = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;letter.txt&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>mailer = mailer.<span class="me1">Mailer</span><span class="br0">&#40;</span><span class="st0">'mail.example.com'</span><span class="br0">&#41;</span><br />
mailer.<span class="me1">send</span><span class="br0">&#40;</span>message<span class="br0">&#41;</span></div>
<h3>Send an email with an attachment</h3>
<div class="dean_ch" style="white-space: wrap;">
message = mailer.<span class="me1">Message</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">From</span> = <span class="st0">&quot;me@example.com&quot;</span><br />
message.<span class="me1">To</span> = <span class="st0">&quot;you@example.com&quot;</span><br />
message.<span class="me1">Subject</span> = <span class="st0">&quot;My Vacation&quot;</span><br />
message.<span class="me1">Body</span> = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;letter.txt&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">attach</span><span class="br0">&#40;</span><span class="st0">&quot;picture.jpg&quot;</span><span class="br0">&#41;</span></p>
<p>mailer = mailer.<span class="me1">Mailer</span><span class="br0">&#40;</span><span class="st0">'mail.example.com'</span><span class="br0">&#41;</span><br />
mailer.<span class="me1">send</span><span class="br0">&#40;</span>message<span class="br0">&#41;</span></div>
<h3>Send an HTML email</h3>
<div class="dean_ch" style="white-space: wrap;">
message = mailer.<span class="me1">Message</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">From</span> = <span class="st0">&quot;me@example.com&quot;</span><br />
message.<span class="me1">To</span> = <span class="st0">&quot;you@example.com&quot;</span><br />
message.<span class="me1">Subject</span> = <span class="st0">&quot;My Vacation&quot;</span><br />
message.<span class="me1">Body</span> = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;letter.txt&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">Html</span> = <span class="st0">&quot;&quot;</span><span class="st0">&quot;This email is in &lt;b&gt;HTML&lt;/b&gt;.<br />
&lt;a href=&quot;</span>http://example.<span class="me1">com</span><span class="st0">&quot;&gt;Here's a link.&lt;/a&gt;&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>mailer = mailer.<span class="me1">Mailer</span><span class="br0">&#40;</span><span class="st0">'mail.example.com'</span><span class="br0">&#41;</span><br />
mailer.<span class="me1">send</span><span class="br0">&#40;</span>message<span class="br0">&#41;</span></div>
<p><a href="/code/mailer_0.1.zip">Download the mailer module (zip file)</a>.</p>
<p><strong>Edit:</strong> Here's the source code of the mailer module.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="co1">#coding: UTF8</span><br />
<span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
mailer module</p>
<p>Simple front end to the smtplib and email modules,<br />
to simplify sending email.</p>
<p>A lot of this code was taken from the online examples in the<br />
email module documentation:<br />
http://docs.python.org/library/email-examples.html</p>
<p>Released under MIT license.</p>
<p>Sample code:</p>
<p>import mailer</p>
<p>message = mailer.Message()<br />
message.From = &quot;</span>me@example.<span class="me1">com</span><span class="st0">&quot;<br />
message.To = &quot;</span>you@example.<span class="me1">com</span><span class="st0">&quot;<br />
message.Subject = &quot;</span>My Vacation<span class="st0">&quot;<br />
message.Body = open(&quot;</span>letter.<span class="me1">txt</span><span class="st0">&quot;, &quot;</span>rb<span class="st0">&quot;).read()<br />
message.attach(&quot;</span>picture.<span class="me1">jpg</span><span class="st0">&quot;)</p>
<p>mailer = mailer.Mailer('mail.example.com')<br />
mailer.send(message)</p>
<p>&quot;</span><span class="st0">&quot;&quot;</span><br />
<span class="kw1">import</span> <span class="kw3">smtplib</span></p>
<p><span class="co1"># Import the email modules we'll need</span><br />
<span class="kw1">from</span> <span class="kw3">email</span> <span class="kw1">import</span> encoders<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">message</span> <span class="kw1">import</span> Message<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">audio</span> <span class="kw1">import</span> MIMEAudio<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">base</span> <span class="kw1">import</span> MIMEBase<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">image</span> <span class="kw1">import</span> MIMEImage<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">multipart</span> <span class="kw1">import</span> MIMEMultipart<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">text</span> <span class="kw1">import</span> MIMEText</p>
<p><span class="co1"># For guessing MIME type based on file name extension</span><br />
<span class="kw1">import</span> <span class="kw3">mimetypes</span></p>
<p><span class="kw1">from</span> <span class="kw3">os</span> <span class="kw1">import</span> path</p>
<p>__version__ = <span class="st0">&quot;0.1&quot;</span><br />
__author__ = <span class="st0">&quot;Ryan Ginstrom&quot;</span><br />
__license__ = <span class="st0">&quot;MIT&quot;</span></p>
<p><span class="kw1">class</span> Mailer<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Represents an SMTP connection.</p>
<p>&nbsp; &nbsp; Use login() to log in with a username and password.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, host=<span class="st0">&quot;localhost&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">host</span> = host<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._usr = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pwd = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> login<span class="br0">&#40;</span><span class="kw2">self</span>, usr, <span class="kw3">pwd</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._usr = usr<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pwd = <span class="kw3">pwd</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> send<span class="br0">&#40;</span><span class="kw2">self</span>, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Send one message or a sequence of messages.</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; Every time you call send, the mailer creates a new<br />
&nbsp; &nbsp; &nbsp; &nbsp; connection, so if you have several emails to send, pass<br />
&nbsp; &nbsp; &nbsp; &nbsp; them as a list:<br />
&nbsp; &nbsp; &nbsp; &nbsp; mailer.send([msg1, msg2, msg3])<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server = <span class="kw3">smtplib</span>.<span class="me1">SMTP</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">host</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>._usr <span class="kw1">and</span> <span class="kw2">self</span>._pwd:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">login</span><span class="br0">&#40;</span><span class="kw2">self</span>._usr, <span class="kw2">self</span>._pwd<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> m <span class="kw1">in</span> msg:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._send<span class="br0">&#40;</span>server, m<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">TypeError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._send<span class="br0">&#40;</span>server, msg<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">quit</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _send<span class="br0">&#40;</span><span class="kw2">self</span>, server, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Sends a single message using the server<br />
&nbsp; &nbsp; &nbsp; &nbsp; we created in send()<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; me = msg.<span class="me1">From</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; you = <span class="br0">&#91;</span>x.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">for</span> x <span class="kw1">in</span> msg.<span class="me1">To</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">sendmail</span><span class="br0">&#40;</span>me, you, msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">class</span> Message<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Represents an email message.</p>
<p>&nbsp; &nbsp; Set the To, From, Subject, and Body attributes as plain-text strings.<br />
&nbsp; &nbsp; Optionally, set the Html attribute to send an HTML email, or use the<br />
&nbsp; &nbsp; attach() method to attach files.</p>
<p>&nbsp; &nbsp; Even when sending an HTML email, you have to set the Body<br />
&nbsp; &nbsp; attribute as the alternative text version.</p>
<p>&nbsp; &nbsp; Send using the Mailer class.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">attachments</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._to = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">From</span> = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Subject</span> = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Body</span> = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Html</span> = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _get_to<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; addrs = <span class="kw2">self</span>._to.<span class="me1">replace</span><span class="br0">&#40;</span><span class="st0">&quot;;&quot;</span>, <span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;, &quot;</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="br0">&#91;</span>x.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> x <span class="kw1">in</span> addrs<span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> _set_to<span class="br0">&#40;</span><span class="kw2">self</span>, to<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._to = to</p>
<p>&nbsp; &nbsp; To = <span class="kw2">property</span><span class="br0">&#40;</span>_get_to, _set_to,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doc=<span class="st0">&quot;&quot;</span><span class="st0">&quot;The recipient(s) of the email.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Separate multiple recipients with commas or semicolons&quot;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> as_string<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Get the email as a string to send in the mailer&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">attachments</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._plaintext<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._multipart<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _plaintext<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Plain text email with no attachments&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">Html</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg &nbsp;= <span class="kw2">self</span>._with_html<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._set_info<span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _with_html<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;There's an html part&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; outer = MIMEMultipart<span class="br0">&#40;</span><span class="st0">'alternative'</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; part1 = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; part2 = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Html</span>, <span class="st0">'html'</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>part1<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>part2<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> outer</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _set_info<span class="br0">&#40;</span><span class="kw2">self</span>, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'Subject'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">Subject</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'From'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">From</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'To'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">To</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _multipart<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;The email has attachments&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEMultipart<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">attach</span><span class="br0">&#40;</span>MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._set_info<span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">preamble</span> = <span class="kw2">self</span>.<span class="me1">Subject</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> filename <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">attachments</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._add_attachment<span class="br0">&#40;</span>msg, filename<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _add_attachment<span class="br0">&#40;</span><span class="kw2">self</span>, outer, filename<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; ctype, encoding = <span class="kw3">mimetypes</span>.<span class="me1">guess_type</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ctype <span class="kw1">is</span> <span class="kw2">None</span> <span class="kw1">or</span> encoding <span class="kw1">is</span> <span class="kw1">not</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># No guess could be made, or the file is encoded (compressed), so</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># use a generic bag-of-bits type.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctype = <span class="st0">'application/octet-stream'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; maintype, subtype = ctype.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">'/'</span>, <span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fp = <span class="kw2">open</span><span class="br0">&#40;</span>filename, <span class="st0">'rb'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> maintype == <span class="st0">'text'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Note: we should handle calculating the charset</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEText<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> maintype == <span class="st0">'image'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEImage<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> maintype == <span class="st0">'audio'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEAudio<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEBase<span class="br0">&#40;</span>maintype, subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">set_payload</span><span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Encode the payload using Base64</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; encoders.<span class="me1">encode_base64</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fp.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Set the filename parameter</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">add_header</span><span class="br0">&#40;</span><span class="st0">'Content-Disposition'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">'attachment'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; filename=path.<span class="me1">basename</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> attach<span class="br0">&#40;</span><span class="kw2">self</span>, filename<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Attach a file to the email. Specify the name of the file;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Message will figure out the MIME type and load the file.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">attachments</span>.<span class="me1">append</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/03/15/a-module-to-send-email-simply-in-python/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
	</channel>
</rss>
