<?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>Mike Desjardins&#039; Series of Tubes &#187; avant</title>
	<atom:link href="http://www.mikedesjardins.net/content/category/avant/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mikedesjardins.net/content</link>
	<description>freelance software developer consultant in portland, maine</description>
	<lastBuildDate>Wed, 02 Feb 2011 00:14:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Don&#8217;t Ignore serialVersionUID</title>
		<link>http://www.mikedesjardins.net/content/2008/12/dont-ignore-serialversionuid/</link>
		<comments>http://www.mikedesjardins.net/content/2008/12/dont-ignore-serialversionuid/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 13:40:00 +0000</pubDate>
		<dc:creator>Mike Desjardins</dc:creator>
				<category><![CDATA[avant]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jee]]></category>
		<category><![CDATA[remoting]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/?p=35</guid>
		<description><![CDATA[Okay,I admit that this one should have totally been obvious to me long ago. But I&#8217;m still a bit of a JEE newcomer (been doing it for almost five years), so perhaps I can be forgiven. If you do a lot of ORM or EJB remoting, you probably deal with a lot of Serializable classes. [...]]]></description>
			<content:encoded><![CDATA[<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/bowl-of-cereal-774086.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 212px; height: 320px;" src="http://mikedesjardins.us/blog/uploaded_images/bowl-of-cereal-774065.jpg" alt="" border="0" /></a>Okay,I admit that this one should have totally been obvious to me long ago.  But I&#8217;m still a bit of a JEE newcomer (been doing it for almost five years), so perhaps I can be forgiven.</p>
<p>If you do a lot of ORM or EJB remoting,  you probably deal with a lot of Serializable classes.  And you&#8217;re probably used to the annoying warning message that you see all the time in your IDE when you&#8217;re working with Serializable classes:</p>
<p>The serializable class BlaBlaBla does not declare a static final serialVersionUID field of type long    BlaBlaBla.java    myProject/src/main/java/us/mikedesjardins/foo/domain/entity    line 44</p>
<p>If you&#8217;re like me, you roll your eyes and politely add a @SuppressWarnings(&#8220;serial&#8221;) to the top of the class definition (or, worse, you just shut the warning message off in your IDE altogether.  Even I don&#8217;t do that!). You reason with yourself that current versions of Java conveniently and automatically compute the serialVersionUID at run-time, so there&#8217;s no need to bother with the formality of a version number on your class &#8211; it&#8217;s just a nuisance holdover from days of Java yore.</p>
<p><span style="font-weight: bold;">IT&#8217;S A TRAP!</span><br />Now that I&#8217;ve found myself well into a new project with this lazy philosophy, I&#8217;m starting to run into problems.  I have a client of my EJB that uses one of these Serializable objects, and I&#8217;m finding that when I make the most trivial changes to my shared classes, I need to compile both the server and the client components.  The two components that were supposed to be loosely coupled are now hopelessly intertwined.  So I did some further research on how the JVM computes the ad-hoc serialVersionUID at runtime when it isn&#8217;t provided.</p>
<p><a href="http://www.javaworld.com/javaworld/jw-02-2006/jw-0227-control.html?page=1">This article over at JavaWorld does a far better and more thorough job of explaining it than I will</a>.  In a nutshell, backward-compatability with respect to serialization and de-serialization is a lot less fragile than the cases that the serialVersionUID generation is protecting you against.  That version generation algorithm computes an SHA hash based on the class name, sorted member variables, modifiers, and interfaces.</p>
<p>In reality, serialization and de-serialization generally only breaks when one of the following things happens to your class (from the aforementioned article at JavaWorld):
<ul>
<li>Delete fields</li>
<li>Change class hierarchy</li>
<li>Change non-static to static</li>
<li>Change non-transient to transient</li>
<li>Change type of a primitive field</li>
</ul>
<p><span style="font-weight: bold;">Ensure Minimal Coupling Between Components</span><br />To ensure that your components which use Serialization have minimal runtime dependencies on each other, you have two options:
<ul>
<li>Declare a specific serialVersionUID, and update it whenever you make a change that breaks backward compatability.</li>
<li>Don&#8217;t rely on any classes for use as transfer objects which will potentially change.  This one is pretty obvious, but sometimes you will be surprised down the road at which classes are modified more often than others.</li>
<li>Don&#8217;t use your own objects at all when transferring data.  Instead, rely on classes like Integers, Strings, or HashMaps to shuttle data around among components.  (Obviously, protocols like SOAP and REST rely on XML documents for this to ensure maximum de-coupling, but you&#8217;re presumably using something like EJB remoting to avoid the complexity or overhead of these protocols).</li>
</ul>
<p><span style="font-style: italic;">Photo Credit: </span><a style="font-style: italic;" href="http://flickr.com/people/thebusybrain/">Mike Johnson</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikedesjardins.net/content/2008/12/dont-ignore-serialversionuid/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python and GConf</title>
		<link>http://www.mikedesjardins.net/content/2007/11/python-and-gconf/</link>
		<comments>http://www.mikedesjardins.net/content/2007/11/python-and-gconf/#comments</comments>
		<pubDate>Fri, 16 Nov 2007 18:15:00 +0000</pubDate>
		<dc:creator>Mike Desjardins</dc:creator>
				<category><![CDATA[applet]]></category>
		<category><![CDATA[avant]]></category>
		<category><![CDATA[awn]]></category>
		<category><![CDATA[gconf]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2007/11/python-and-gconf/</guid>
		<description><![CDATA[The weather applet and clock/calendar applet for the Avant Window Navigator both use GConf to store their configuration settings. GConf is part of the GNOME environment on Linux. It maintains a hierarchical set of configuration data in (key,value) pairs, much like the registry on Windows or the &#8220;plist files&#8221; on OSX. One of the nice [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://wiki.awn-project.org/index.php?title=Weather_Applet">weather applet</a> and <a href="http://wiki.awn-project.org/index.php?title=Clock/Calendar_Applet">clock/calendar applet</a> for the <a href="http://www.awn-project.org/">Avant Window Navigator</a> both use <a href="http://www.gnome.org/projects/gconf/">GConf</a> to store their configuration settings.  GConf is part of the GNOME environment on Linux.  It maintains a hierarchical set of configuration data in (key,value) pairs, much like the registry on Windows or the &#8220;plist files&#8221; on OSX.  One of the nice things about GConf is that you can register your application to receive notifications in a callback function whenever any interesting configuration values change.</p>
<p>I noticed that there weren&#8217;t a lot of tutorials out there on the topic of mixing Python with GConf, so I decided to write one.</p>
<p>First, you&#8217;ll need to import the Python bindings for GConf:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> gconf</pre></div></div>

<p>Next, you want to create a GConf &#8220;client&#8221; in your Python app.  You&#8217;ll probably want to do this in an __init__() function somewhere.  You&#8217;ll also want to register your application to receive notifications when ever your configuration values change.  The hierarchy of configuration values in GConf follows the familiar slash-separated path notation.  For example, the configuration values for my AWN weather applet are stored in /apps/avant-window-navigator/applets/weather.  So, if I want to register a callback named config_event to be called whenever configuration values on that path are modified, I&#8217;d do the following:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">self</span>.<span style="color: black;">gconf_client</span> = gconf.<span style="color: black;">client_get_default</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">self</span>.<span style="color: black;">gconf_client</span>.<span style="color: black;">notify_add</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/apps/avant-window-navigator/applets/weather&quot;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">config_event</span><span style="color: black;">&#41;</span></pre></div></div>

<p><span style="font-size:100%;">I usually write a generic &#8220;get_config&#8221; function, and have the callback call get_config.  That way, I can use the same configuration code when I initialize.  The config callback then looks simple&#8230; something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> config_event<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, gconf_client, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
  <span style="color: #008000;">self</span>.<span style="color: black;">get_config</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><span style="font-size:100%;">The kwargs parameter gives you a list of parameters that changed.  You can fine-tune your configuration code based on this, but I usually just ignore it and re-read everything because I don&#8217;t usually have very many parameters.</p>
<p>GConf provides functions for reading your parameters.  They look like this:</span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">foo = <span style="color: #008000;">self</span>.<span style="color: black;">gconf_client</span>.<span style="color: black;">get_string</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/path/to/my/config/data/foo&quot;</span><span style="color: black;">&#41;</span>
bar = <span style="color: #008000;">self</span>.<span style="color: black;">gconf_client</span>.<span style="color: black;">get_int</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/path/to/my/config/data/bar&quot;</span><span style="color: black;">&#41;</span>
baz = <span style="color: #008000;">self</span>.<span style="color: black;">gconf_client</span>.<span style="color: black;">get_bool</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/path/to/my/config/data/baz&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><span style="font-size:100%;">All of the functions except </span><span style=";font-family:courier new;font-size:100%;"  >get_bool</span>return None if the key isn&#8217;t found.  Oddly, <span style=";font-family:courier new;font-size:100%;"  >get_bool</span> seems to return False if the key isn&#8217;t found.  In my configuration code, I like to initialize my GConf values when the key isn&#8217;t found.  So when if my code were to read the &#8220;foo&#8221; parameter like the above example, it&#8217;d actually be coded something like this:</span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">foo = <span style="color: #008000;">self</span>.<span style="color: black;">gconf_client</span>.<span style="color: black;">get_string</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/path/to/my/config/foo&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">if</span> foo == <span style="color: #008000;">None</span>:
  <span style="color: #008000;">self</span>.<span style="color: black;">gconf_client</span>.<span style="color: black;">set_string</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/path/to/my/config/foo&quot;</span>, <span style="color: #483d8b;">&quot;Default Value&quot;</span><span style="color: black;">&#41;</span>
  foo = <span style="color: #483d8b;">&quot;Default Value&quot;</span></pre></div></div>

<p><span style="font-size:100%;"><br />And I usually wrap the above idiom in its own function that accepts a key name and a default value.<br /></span><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.dragonflymarsh.com/blog/uploaded_images/Screenshot-Configuration-Editor---weather-703851.png"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 264px; height: 210px;" src="http://mikedesjardins.us/blog/uploaded_images/Screenshot-Configuration-Editor---weather-703844.png" alt="" border="0" /></a><br /><span style="font-size:100%;">Note that you can edit and interact with your GConf settings in realtime using </span><span style="font-size:100%;">the GNOME configuration tool.  If you use Ubuntu, then this utility may be found under the &#8220;System Tools&#8221; menu.  Editing configuration values in the configuration tool will result in your callback being executed as you might expect.</p>
<p>This also makes creating a configuration dialog easy.  The configuration dialog just needs to write its updated values to gconf when the user clicks Apply or OK.  If you&#8217;ve created a callback and generic configuration function, then the application will automatically reconfigure itself after the user applies their modifications!</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikedesjardins.net/content/2007/11/python-and-gconf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>L10N with Python in Avant Window Navigator Applets</title>
		<link>http://www.mikedesjardins.net/content/2007/10/l10n-with-python-in-avant-window/</link>
		<comments>http://www.mikedesjardins.net/content/2007/10/l10n-with-python-in-avant-window/#comments</comments>
		<pubDate>Tue, 30 Oct 2007 18:23:00 +0000</pubDate>
		<dc:creator>Mike Desjardins</dc:creator>
				<category><![CDATA[avant]]></category>
		<category><![CDATA[awn]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[l10n]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2007/10/l10n-with-python-in-avant-window-navigator-applets/</guid>
		<description><![CDATA[It&#8217;s been a while since I blogged about my latest &#8220;hobby&#8221; (oh, how my wife would cringe), writing Python-based applets for the Avant Window Navigator. I&#8217;ve been spending a lot of time working on my clock/calendar applet lately, but today I&#8217;m going to go back to my weather applet because it&#8217;s more interesting to write [...]]]></description>
			<content:encoded><![CDATA[<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.dragonflymarsh.com/blog/uploaded_images/file-788164.png"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://www.dragonflymarsh.com/blog/uploaded_images/file-788161.png" alt="" border="0" /></a>It&#8217;s been a while since I blogged about my latest &#8220;hobby&#8221; (oh, how my wife would cringe), writing Python-based applets for the <a href="http://wiki.awn-project.org/">Avant Window Navigator</a>.  I&#8217;ve been spending a lot of time working on my <a href="http://wiki.awn-project.org/index.php?title=Clock/Calendar_Applet">clock/calendar applet</a> lately, but today I&#8217;m going to go back to my <a href="http://wiki.awn-project.org/index.php?title=Weather_Applet">weather applet</a> because it&#8217;s more interesting to write about.</p>
<p>A while ago, I decided it was time to add some alternate (that is, non-English) language support to the applet.  The de-facto standard tool to accomplish this is the Python variant of GNU&#8217;s <a href="http://docs.python.org/lib/module-gettext.html">gettext</a>.  I found a couple of resources that helped guide me through this.  The first was the <a href="http://wiki.laptop.org/go/Python_i18n">wiki</a> for the &#8220;one laptop per child&#8221; project, which does a lot of L10N in Python.    The second was an excellent <a href="http://http//www.learningpython.com/2006/12/03/translating-your-pythonpygtk-application/">post</a> in the &#8220;Learning Python&#8221; blog (the author doesn&#8217;t give his/her name in the &#8220;<a href="http://www.learningpython.com/who-am-i/">Who am I</a>&#8221; section, otherwise I&#8217;d give props).  And of course, there&#8217;s always the official Python <a href="http://docs.python.org/lib/node732.html">library documentation</a>, too.</p>
<p>The first step is to import the gettext libraries into your Python code, and do some setup work, thusly:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">APP=<span style="color: #483d8b;">&quot;awn-weather-applet&quot;</span>
DIR=<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span> <span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">'/locale'</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">locale</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">gettext</span>
<span style="color: #808080; font-style: italic;">#locale.setlocale(locale.LC_ALL, '')</span>
<span style="color: #dc143c;">gettext</span>.<span style="color: black;">bindtextdomain</span><span style="color: black;">&#40;</span>APP, DIR<span style="color: black;">&#41;</span>
<span style="color: #dc143c;">gettext</span>.<span style="color: black;">textdomain</span><span style="color: black;">&#40;</span>APP<span style="color: black;">&#41;</span>
_ = <span style="color: #dc143c;">gettext</span>.<span style="color: #dc143c;">gettext</span></pre></div></div>

<p>(Note: Made an edit to the above source code on Nov 16 2007 &#8211; evidently, the DIR parameter needs the full path to work properly)</p>
<p>Now, here&#8217;s what we&#8217;re actually doing.  The call to <span style="font-family:courier new;">bindtextdomain</span> is <span style="font-style: italic;">binding</span> the <span style="font-weight: bold;">awn-weather-applet</span> domain to the <span style="font-weight: bold;">locale</span> subdirectory. When the applet is deployed, it has a locale directory right underneath the main script, weather.py.  The directory argument of <span style="font-family:courier new;">bindtextdomain</span> is relative, so we&#8217;re pointing gettext at that directory.  We&#8217;re basically telling gettext to look in the locale subdirectory for files named <span class="file"><var>language</var>/LC_MESSAGES/<var></var>awn-weather-applet.mo, where language is the two-letter language code defined by the environment (more on that later).</p>
<p>It should be noted that, customarily, locale files are stored in a default location which is a more global place in the filesystem, e.g. /usr/share/locale/<span style="font-style: italic;">language</span>/LC_MESSAGES.  If you don&#8217;t supply a directory to the <span style="font-family:courier new;">bindtextdomain</span> method call, gettext will use the default directory for the system.  I opted <span style="font-style: italic;">not</span> to use the default filesystem location because I wanted non-superusers to be able to easily use language files that I supply with the applet, using the standard AWN applet installation mechanism.  Requiring the user to put .mo files in the /usr/share directory tree isn&#8217;t an option.</p>
<p>The call to <span style="font-family:courier new;">textdomain</span> sets the global domain to awn-weather-applet.  Essentially we&#8217;re telling gettext that all future calls into gettext should use the </span><span class="file">awn-weather-applet domain as its source for translations.</p>
<p>Lastly, the line that reads <span style="font-family:courier new;">_ = gettext.gettext()</span> defines a convenient alias that we will use to identify strings in our code that need translation.  If you&#8217;re familiar with i18n of C applications, this will look quite familiar; in the C implementation, an identically named macro is used for the same purpose.</p>
<p>The next step is to read through the code to identify the literal strings that will be translated.  Generally, any UI element that a user will see is a candidate for translation.  Things like log and console output are not as important.  When we find a candidate string, we wrap it in _( ).  For example, this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">self</span>.<span style="color: black;">dialog</span>.<span style="color: black;">set_title</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Forecast&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>becomes<br /></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">self</span>.<span style="color: black;">dialog</span>.<span style="color: black;">set_title</span><span style="color: black;">&#40;</span>_<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Forecast&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Because of the alias at the top of the source file, what we&#8217;re <span style="font-style: italic;">really</span> doing is this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">self</span>.<span style="color: black;">dialog</span>.<span style="color: black;">set_title</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">gettext</span>.<span style="color: #dc143c;">gettext</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Forecast&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>It&#8217;s a good thing we have the shorthand version!</p>
<p>As I alluded to earlier, gettext does its magic by reading files that ends in an .mo extension.  At runtime, it reads the string that&#8217;s passed into it (in the above example, &#8220;Forecast&#8221;), then looks up that string in the proper .mo file to see if a translation is available.  If it finds an entry, it returns the translated string, otherwise it just returns the string that was passed into it.  So our next task is to create the .mo files.</p>
<p>Creating .mo files is a three step process.  First, we need to run a tool that extracts all of the strings to be translated into a usable text file that a translator can edit.  The tool to do this is called xgettext.  The command line to run looks like this:<br /><span style="font-family:monospace;"><br /></span></p>
<pre>
xgettext --language=Python --keyword=_ --output=awn-weather-applet.pot *.py</pre>
<p>This command generates an output file named awn-weather-applet.pot which acts as a template for translators to do their translation.  The file has a bunch of lines that look like this:</p>
<pre>
#: weather.py:127
msgid "Forecast"
msgstr ""
</pre>
<p>So, let&#8217;s say we want to make a Spanish translation of the weather applet.  First, we&#8217;d make a copy of this file, and name it something sensible like awn-weather-applet.po (note, you can also use the msginit tool, which does a few other housekeeping things for you like fill in the e-mail address).  We&#8217;d find all the lines that start with msgid, translate it, and put the result in the following line&#8217;s msgstr, like this:</p>
<pre>
#: weather.py:127
msgid "Forecast"
msgstr "Pronóstico"
</pre>
<p>Next, we need to &#8220;compile&#8221; the awn-weather-applet.po file into an awn-weather-applet.mo file, so that it&#8217;s usable by gettext at runtime.  This is done using the msgfmt command, like this:</p>
<p>msgfmt awn-weather-applet.po -o awn-weather-applet.mo</p>
<p>That&#8217;s it!  Now all you need to do is ensure that the awn-weather-applet.mo file ends up in the (base of weather applet)/locale/es/LC_MESSAGES directory, and Spanish translations work!<br /><span class="file"><span style="font-size:85%;"><span style="font-family:courier new;"></span></span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikedesjardins.net/content/2007/10/l10n-with-python-in-avant-window/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Developing Applets for AWN: Drawing the Icon</title>
		<link>http://www.mikedesjardins.net/content/2007/10/developing-applets-for-awn-drawing-icon/</link>
		<comments>http://www.mikedesjardins.net/content/2007/10/developing-applets-for-awn-drawing-icon/#comments</comments>
		<pubDate>Mon, 08 Oct 2007 14:45:00 +0000</pubDate>
		<dc:creator>Mike Desjardins</dc:creator>
				<category><![CDATA[applet]]></category>
		<category><![CDATA[avant]]></category>
		<category><![CDATA[awn]]></category>
		<category><![CDATA[cairo]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2007/10/developing-applets-for-awn-drawing-the-icon/</guid>
		<description><![CDATA[(Continued from previous two posts)If you&#8217;re familiar with the Avant Window Navigator, then you know that a fair amount of the project revolves around eye candy and visual effects. Making an applet that is consistent with the user&#8217;s expectations with respect to visual effects (e.g., reflection, bouncing, rotating, etc.) is very important. Fortunately, Neil and [...]]]></description>
			<content:encoded><![CDATA[<p>(Continued from previous two posts)<br />If you&#8217;re familiar with the Avant Window Navigator, then you know that a fair amount of the project revolves around eye candy and visual effects.  Making an applet that is consistent with the user&#8217;s expectations with respect to visual effects (e.g., reflection, bouncing, rotating, etc.) is very important.  Fortunately, Neil and Co. have made this quite straightforward.    By simply sub-classing the awn.AppletSimple class, your applet will inherit all of the special effects that it should. </p>
<p>Unfortunately, there&#8217;s one small trick you need to work around.  If your applet is so simple that it just needs a single, static icon, then sub-classing awn.AppletSimple, followed by a call to set_icon, works great.  It gets more difficult if you need to draw dynamic content in the area usually occupied by the icon.</p>
<p>The problem is that set_icon (as well as its misunderstood cousin, set_temp_icon) takes a Pixbuf as its input parameter.  However, the drawing framework for doing just about anything, especially loading PNGs, is <a href="http://cairographics.org">cairo</a>.  Cairo has no native support for converting a surface to a Pixbuf.  I discovered a trick for doing this by looking at the source code for the PyClock and BlingSwitcher applets.  Let&#8217;s say you have a Cairo image surface that you&#8217;ve created from an existing PNG, thusly:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">cs = cairo.<span style="color: black;">ImageSurface</span>.<span style="color: black;">create_from_png</span><span style="color: black;">&#40;</span>iconName<span style="color: black;">&#41;</span>
ct = cairo.<span style="color: black;">Context</span><span style="color: black;">&#40;</span>cs<span style="color: black;">&#41;</span>
ct.<span style="color: black;">set_source_surface</span><span style="color: black;">&#40;</span>cs<span style="color: black;">&#41;</span>
ct.<span style="color: black;">paint</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>&#8230;and you want to get a Pixbuf from that image.  The following function takes the surface, writes it to a PNG that is stored in a string, then uses the Pixbuf loader to load it from that PNG string:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># Stolen from diogodivision's &quot;BlingSwitcher&quot;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> get_pixbuf_from_surface<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, surface<span style="color: black;">&#41;</span>:
  sio = <span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  surface.<span style="color: black;">write_to_png</span><span style="color: black;">&#40;</span>sio<span style="color: black;">&#41;</span>
  sio.<span style="color: black;">seek</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
  loader = gtk.<span style="color: black;">gdk</span>.<span style="color: black;">PixbufLoader</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  loader.<span style="color: black;">write</span><span style="color: black;">&#40;</span>sio.<span style="color: black;">getvalue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  loader.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> loader.<span style="color: black;">get_pixbuf</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Neat, huh?  This is how I manage to display the temperature on the weather applet.  I load up the icon into an ImageSurface, write the text on top of it by calling show_text, call the function above to convert the ImageSurface to a PixBuf, then call set_temp_icon using the new PixBuf.</p>
<p>You can see it in action by <a href="http://www.mikedesjardins.us/awn/weather-applet-0.8.tar.gz">downloading the weather applet</a>, and looking in weather.py. The relevant code is in the draw_current_conditions function.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikedesjardins.net/content/2007/10/developing-applets-for-awn-drawing-icon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parsing XML with Python and minidom</title>
		<link>http://www.mikedesjardins.net/content/2007/10/parsing-xml-with-python-and-minidom/</link>
		<comments>http://www.mikedesjardins.net/content/2007/10/parsing-xml-with-python-and-minidom/#comments</comments>
		<pubDate>Thu, 04 Oct 2007 15:47:00 +0000</pubDate>
		<dc:creator>Mike Desjardins</dc:creator>
				<category><![CDATA[avant]]></category>
		<category><![CDATA[awn]]></category>
		<category><![CDATA[minidom]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2007/10/parsing-xml-with-python-and-minidom/</guid>
		<description><![CDATA[(Continued from my last post)So, the first thing I needed to do when creating my weather applet for Avant Window Navigator was actually parse weather data from a weather source. After messing around with Google&#8217;s weather API for a while, I decided to use weather.com&#8216;s web service. weather.com has a well-documented, straightforward, predictable XML API. [...]]]></description>
			<content:encoded><![CDATA[<p>(Continued from my last post)<br />So, the first thing I needed to do when creating my weather applet for Avant Window Navigator was actually parse weather data from a weather source.  After messing around with Google&#8217;s weather API for a while, I decided to use <a href="http://xoap.weather.com/">weather.com</a>&#8216;s web service.  weather.com has a well-documented, straightforward, predictable XML API.  To parse the XML, I chose <a href="http://docs.python.org/lib/module-xml.dom.minidom.html">minidom</a>.  Minidom is a &#8220;Lightweight DOM Implementation.&#8221;  Here&#8217;s how it works:  Let&#8217;s say you have an XML document that supplies a pizza menu, at some URL.  Here&#8217;s the XML:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.dragonflymarsh.com/blog/uploaded_images/pizza-xml-2-706698.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://www.dragonflymarsh.com/blog/uploaded_images/pizza-xml-2-706697.png" alt="" border="0" /></a>In the python script that will be parsing this, you&#8217;d want to import the minidom package.  Let&#8217;s assume that the above XML is served by the URL http://menu.pizzaplace.us, so you&#8217;ll want to import urllib as well.  The python code to read up the XML Document might look like the following:</p>
<p><span style="font-family:courier new;"><span style="font-size:85%;"><br />from xml.dom import minidom<br />import urllib<br />import sys<br />try:<br />&nbsp;usock = urllib.urlopen(&#8216;http://menu.pizzaplace.us&#8217;)<br />&nbsp;xmldoc = minidom.parse(usock)<br />&nbsp;usock.close()<br />except:<br />&nbsp;print &#8220;Something really bad happened! &#8220;, sys.exc_info()[0]<br /></span></span></p>
<p>Easy, right? Now we want to get the actual data out of the Pizza Menu.  Everything in your DOM tree is a Node.  This includes text between element tags.  In fact, in minidom, the whitespace between strings of text is a node, too (more on that in a minute!).  To fetch nodes, you use the <span style="font-weight: bold;">getElementsByTagName</span> function.  This function returns a List of nodes with matching element tag names.  Another handy function is <span style="font-weight: bold;">getAttribute</span>. As you might expect, it returns the value for an attribute on a particular element. </p>
<p>Let&#8217;s say we want to iterate through all of the pizzas on the pizza-menu, printing the type of pizza.  That code would look like this:</p>
<p><span style="font-family:courier new;"><span style="font-size:85%;"><br />from xml.dom import minidom<br />import urllib<br />try:<br />&nbsp;usock = urllib.urlopen(&#8216;http://menu.pizzaplace.us&#8217;)<br />&nbsp;xmldoc = minidom.parse(usock)<br />&nbsp;usock.close()<br /><span style="font-weight: bold;">&nbsp;pizza_list = xmldoc.getElementsByTagName(&#8216;pizza&#8217;)</span><br /><span style="font-weight: bold;">&nbsp;for pizza_element in pizza_list:</span><br /><span style="font-weight: bold;">&nbsp;&nbsp;pizza_type = pizza_element.getAttribute(&#8216;type&#8217;)</span><br /><span style="font-weight: bold;">&nbsp;&nbsp;print &#8216;Pizza Type: %s&#8217; % pizza_type</span><br />except:<br />&nbsp;print &#8220;Something really bad happened! &#8220;, sys.exc_info()[0]<br /></span></span></p>
<p>Next, let&#8217;s pretend that &#8220;heart-attack-special&#8221; pizza sounds really appetizing, and we want to estimate just how much our cholesterol count will spike if we have a slice.  We probably want to iterate over the toppings on that pizza to perform that evaluation.  To that end, we will hunt for the pizza with the type &#8220;heart-attack-special&#8221;, grab that node, then iterate over the topping sub-nodes.  Here&#8217;s how we would do that:</p>
<p><span style="font-family:courier new;"><span style="font-size:85%;"><br />from xml.dom import minidom<br />import urllib<br />try:<br />&nbsp;usock = urllib.urlopen(&#8216;http://menu.pizzaplace.us&#8217;)<br />&nbsp;xmldoc = minidom.parse(usock)<br />&nbsp;usock.close()<br />&nbsp;pizza_list = xmldoc.getElementsByTagName(&#8216;pizza&#8217;)<br />&nbsp;for pizza_element in pizza_list:<br />&nbsp;&nbsp;pizza_type = pizza_element.getAttribute(&#8216;type&#8217;)<br />&nbsp;&nbsp;print &#8216;Pizza Type: %s&#8217; % pizza_type<br /><span style="font-weight: bold;">&nbsp;&nbsp;if pizza_type == &#8216;heart-attack-special&#8217;:</span><br /><span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;topping_list = pizza_element.getElementsByName(&#8216;topping&#8217;)</span><br /><span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;for topping_element in topping_list:</span><br /><span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;# (do something here)</span><br />except:<br />&nbsp;print &#8220;Something really bad happened! &#8220;, sys.exc_info()[0]<br /></span></span></p>
<p>As you can see, the pizza_element is a node like any other node, so you can call <span style="font-weight: bold;">getElementsByName</span> on it to get any child nodes of this pizza element.  The toppings  (pepperoni, sausage, hamburg, canadian bacon, and ham) are themselves child nodes of their respective elements.  Each node has a nodeType property which describes the nature of that node.  The nodeTypes are TEXT_NODE, ELEMENT_NODE, ATTRIBUTE_NODE, and DOCUMENT_NODE.  Thus, the word &#8220;pepperoni&#8221; is a child node of the first topping node, and is of type TEXT_NODE.</p>
<p>You might be surprised to learn that the fourth topping node on the heart-attack-special is comprised of <span style="font-style: italic;">three</span> child text nodes.  The text &#8220;canadian bacon&#8221; has a child with the value bacon, a child with a single character of whitespace, and a child with the value bacon.  This is not usually how we want to access the data in our XML documents; we&#8217;d prefer that &#8220;canadian bacon&#8221; be treated as a single node comprised of one string. </p>
<p>To make the data behave the way we expect it to, we can introduce our own simple utility method called <span style="font-weight: bold;">getText</span>.  This function concatenates all child nodes of the supplied node list which are of type TEXT_NODE.  It looks like this:</p>
<p><span style="font-size:85%;"><span style="font-family: courier new;"><br />def getText(nodelist):<br />&nbsp;rc = &#8220;&#8221;<br />&nbsp;for node in nodelist:<br />&nbsp;&nbsp;if node.nodeType == node.TEXT_NODE:<br />&nbsp;&nbsp;&nbsp;rc = rc + node.data<br />&nbsp;return rc<br /></span></span>   </p>
<p>To use it, we&#8217;d pass it the parent node of the text we&#8217;re interested in.  Going back to our original example, we can use the getText function to print out each topping on our heart-attack-special pizza:</p>
<p><span style="font-size:85%;"><span style="font-family: courier new;"><br />from xml.dom import minidom<br />import urllib<br />try:<br />&nbsp;usock = urllib.urlopen(&#8216;http://menu.pizzaplace.us&#8217;)<br />&nbsp;xmldoc = minidom.parse(usock)<br />&nbsp;usock.close()<br />&nbsp;pizza_list = xmldoc.getElementsByTagName(&#8216;pizza&#8217;)<br />&nbsp;for pizza_element in pizza_list:<br />&nbsp;&nbsp;pizza_type = pizza_element.getAttribute(&#8216;type&#8217;)<br />&nbsp;&nbsp;print &#8216;Pizza Type: %s&#8217; % pizza_type<br />&nbsp;&nbsp;if pizza_type == &#8216;heart-attack-special&#8217;:<br />&nbsp;&nbsp;&nbsp;topping_list = pizza_element.getElementsByName(&#8216;topping&#8217;)<br />&nbsp;&nbsp;&nbsp;for topping_element in topping_list:<br /><span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;topping_text = getText(topping_element)</span><br /><span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;print &#8221;  Topping: %s&#8221; % topping_text</span><br />except:<br />&nbsp;print &#8220;Something really bad happened! &#8220;, sys.exc_info()[0]<br /></span></span></p>
<p>The XML-parsing portions of the weather applet that I wrote for the Avant Window Navigator aren&#8217;t much more complicated than this.  You can download the source code for the weather applet <a href="http://www.dragonflymarsh.com/awn/weather-applet-08.tar.gz">here</a>. The parts which parse weather.com&#8217;s data are in the weather.py script, in the <span style="font-weight: bold;">get_conditions</span> and <span style="font-weight: bold;">get_forecast</span> functions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikedesjardins.net/content/2007/10/parsing-xml-with-python-and-minidom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Applets for AWN</title>
		<link>http://www.mikedesjardins.net/content/2007/10/applets-for-awn/</link>
		<comments>http://www.mikedesjardins.net/content/2007/10/applets-for-awn/#comments</comments>
		<pubDate>Wed, 03 Oct 2007 16:12:00 +0000</pubDate>
		<dc:creator>Mike Desjardins</dc:creator>
				<category><![CDATA[avant]]></category>
		<category><![CDATA[awn]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[weather]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/?p=22</guid>
		<description><![CDATA[I use Linux on the desktop at work. As a Mac owner, I was frustrated by the lack of a usable Dock, until I stumbled across a project called the Avant Window Navigator. Not only is it a cool dock, but it comes with oodles of eye-candy, which I&#8217;m a sucker for. Here&#8217;s a screenshot [...]]]></description>
			<content:encoded><![CDATA[<p>I use Linux on the desktop at work. As a Mac owner, I was frustrated by the lack of a usable Dock, until I stumbled across a project called the <a href="http://wiki.awn-project.org/">Avant Window Navigator</a>.  Not only is it a cool dock, but it comes with oodles of eye-candy, which I&#8217;m a sucker for.</p>
<p>Here&#8217;s a screenshot of my dock:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.dragonflymarsh.com/blog/uploaded_images/Screenshot-761483.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://www.dragonflymarsh.com/blog/uploaded_images/Screenshot-761480.png" alt="" border="0" /></a>You hear a lot about open source developers who got involved because they needed to &#8220;scratch an itch.&#8221;  I happen to do web development in Java, and I had come to rely on my Gnome CPU Meter applet to tell me when Tomcat had finished deploying (there was always a spike while it was deploying a war file, and then a dropoff when it was finished).  I didn&#8217;t have that in AWN.  Fortunately, you can make applets for it.</p>
<p>So the first applet I created, after a &#8220;Hello World&#8221; applet and a clock, was a C-based applet called CPU Meter (incidentally, my &#8220;Hello World&#8221; applet is now part of the awn-extras package).  For the CPU Meter, I stole some code from the <a href="http://www.blogger.com/img/gl.link.gif">Gnome System Monitor</a>, mashed it into my Hello World applet, read up on the <a href="http://www.cairographics.org/">Cairo Graphics API</a> and <a href="http://library.gnome.org/devel/gtk/2.12/"><span style="text-decoration: underline;">GTK+ API</span></a>, and cobbled together a working CPU load grapher.  Later on, another developer came up with an applet called &#8220;AwnTop&#8221; (a process listing applet), and he merged my stuff in with his stuff.  The new applet is now called the AWN System Monitor.</p>
<p>Next, I decided to create a weather applet.  All of the other developers had started writing their applets in Python, so I figured it was as good time as any to learn Python!  I&#8217;ve gotta say I LOVE Python.  It&#8217;s JavaScript&#8217;s simplicity, Shell scripting&#8217;s ease-of-use, and Perl&#8217;s power&#8230; and it&#8217;s incredibly easy to read and learn.  Here&#8217;s a picture of the weather applet in action:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.dragonflymarsh.com/blog/uploaded_images/Screenshot-1-779658.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://www.dragonflymarsh.com/blog/uploaded_images/Screenshot-1-779652.png" alt="" border="0" /></a>Cool, huh?</p>
<p>Well, I really didn&#8217;t intend for this post to be a brag session.  I wanted it to be a how-to develop applets for AWN using Python.  But now I guess I&#8217;ll leave that for the next post!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikedesjardins.net/content/2007/10/applets-for-awn/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

