<?xml version="1.0" encoding="UTF-8"?>

<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<title type="text">Juri Pakaste - The Blog</title>
<subtitle type="html"><![CDATA[
the world we create
]]></subtitle>
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/index.atom</id>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi" />
<link rel="self" type="application/atom+xml" href="http://juripakaste.fi/cgi/pyblosxom.cgi/index.atom" />


<author>
<name>Juri Pakaste</name>
<uri>http://juripakaste.fi/cgi/pyblosxom.cgi/index.atom</uri>
<email>juri@iki.fi</email>
</author>
<rights>Copyright 2002-2008 Juri Pakaste</rights>
<generator uri="http://pyblosxom.sourceforge.net/" version="1.4.3 01/10/2008">
PyBlosxom http://pyblosxom.sourceforge.net/ 1.4.3 01/10/2008
</generator>

<updated>2012-05-01T11:35:49Z</updated>
<!-- icon?  logo?  -->

<entry>
<title type="html">ZeroMQ, iOS and Python</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2012/05/01/zeromq-ios-python</id>
<updated>2012-05-01T11:35:49Z</updated>
<published>2012-05-01T11:35:49Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/zeromq-ios-python.html" />
<content type="html">&lt;p&gt;I wrote some example code for you.&lt;/p&gt;

&lt;p&gt;Background: last week a coworker asked me what&apos;s the flavor &lt;em&gt;du jour&lt;/em&gt; in two-way communication between a network server and an iOS app, should he just go with BSD sockets or is there something better? I suggested he should take a look at &lt;a href=&quot;http://www.zeromq.org/&quot;&gt;ZeroMQ&lt;/a&gt;. Not that I actually knew very much at all about it, but I had heard the name and seen that some people were pretty enthustiastic about it.&lt;/p&gt;

&lt;p&gt;Turns out he had deadlines and wasn&apos;t too keen on building the library with an outdated zsh script that didn&apos;t seem to work.&lt;/p&gt;

&lt;p&gt;I started fiddling with it myself on the weekend to have some idea about what I&apos;m talking about. True enough that the script provided on the web page wasn&apos;t up to date, and once I fixed it I got only an ARM binary which isn&apos;t very useful in development when you want to test on the iPhone Simulator. After some more poking I finally managed to massage a working fat library out of it. And &lt;a href=&quot;https://github.com/jeremy-w/objc-zmq&quot;&gt;objc-zmq&lt;/a&gt; provided a nice simple Objective-C wrapper around the C API.&lt;/p&gt;

&lt;p&gt;Not satisfied with playing with just one unknown technology, I thought I&apos;d do the server in Clojure. After shaving the JNI yak for a couple of hours, trying to build a working version if the Java binding, I decided it wasn&apos;t worth it. Python was an easy fallback, but to keep things at least moderately exciting I used &lt;a href=&quot;http://www.gevent.org/&quot;&gt;gevent&lt;/a&gt; which was also something I hadn&apos;t tried before.&lt;/p&gt;

&lt;p&gt;It worked out pretty nice. The Python server is extremely simple and the iOS app isn&apos;t complex either. This hardly counts as a strenuous test of ZeroMQ, but at least from the code perspective it was really pleasant to work with. No hassle with buffers, just complete messages from an extremely simple API that enables the most common communication patterns with a couple of keywords. They wisely keep out of the marshalling business, telling people to use Protocol Buffers or something else for defining message formats.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://bitbucket.org/juri/zeromq-ios-py&quot;&gt;example project&lt;/a&gt; is available on Bitbucket. It works on my computer at the moment; see the Bitbucket page for details about the bits it requires.&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Unit testing Cocoa code with MacRuby</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2010/11/30/rcrunner</id>
<updated>2010-11-30T18:45:10Z</updated>
<published>2010-11-30T18:45:10Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/rcrunner.html" />
<content type="html">&lt;p&gt;Announcing &lt;a href=&quot;https://bitbucket.org/juri/rcrunner/wiki/Home&quot;&gt;RCRunner&lt;/a&gt;, a GUI test runner for &lt;a href=&quot;http://www.macruby.org/&quot;&gt;MacRuby&lt;/a&gt; and Cocoa.&lt;/p&gt;

&lt;p&gt;Cocoa unit testing can be a pain. In addition to the usual difficulties of writing tests for user interface heavy code, the Apple sanctioned solution, SenTestingKit, can isn&apos;t the greatest testing framework around and the default way of using it rules out debugger.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/gabriel/gh-unit&quot;&gt;GHUnit&lt;/a&gt; helps somewhat. It&apos;s a GUI test runner with additional testing methods. However, with it you are still writing your tests in Objective-C. On the plus side it&apos;s the same language you&apos;re probably writing your app in. On the minus side Objective-C can be verbose and sometimes, especially when writing test code, brevity would be welcome.&lt;/p&gt;

&lt;p&gt;Enter MacRuby. You get the conciseness of Ruby with full access to your Objective-C classes. And Ruby probably has the greatest density of testing frameworks per active programmer among all the languages in popular use today.&lt;/p&gt;

&lt;p&gt;There&apos;s a nice article about &lt;a href=&quot;http://www.macruby.org/recipes/tdd-in-objective-c-with-macruby.html&quot;&gt;TDD, Objective-C and MacRuby&lt;/a&gt; on the MacRuby site. However, the approach taken in it still uses a Xcode build phase script to accomplish testing. That makes debugging hard and you have to hunt through the build logs for your errors.&lt;/p&gt;

&lt;p&gt;RCRunner is a separate GUI program you run. You tell it names of Ruby modules and it uses any test cases it finds[1]. You can breakpoint your code and thanks to Ruby, reload the test code. You can inspect errors and log output test by test.&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;

&lt;p&gt;[1] At the moment it supports only MiniTest but adding support for other frameworks isn&apos;t difficult.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Using Firefox as Flash playing Safari fallback</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2010/11/10/safari_flash_firefox_fallback</id>
<updated>2010-11-10T16:11:28Z</updated>
<published>2010-11-10T16:11:28Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/safari_flash_firefox_fallback.html" />
<content type="html">&lt;p&gt;If you want to go &lt;a href=&quot;http://daringfireball.net/2010/11/flash_free_and_cheating_with_google_chrome&quot;&gt;Flashless&lt;/a&gt; on Mac and Safari, it&apos;s possible to use Firefox as a fallback, too, not just Chrome. While Firefox does load Plugins from &lt;code&gt;/Library/Internet Plug-Ins&lt;/code&gt; and &lt;code&gt;~/Library/Internet Plug-Ins&lt;/code&gt;, it looks in other places too. I just tested and it seems to work fine from &lt;code&gt;~/Library/Application Support/Firefox/Profiles/&amp;lt;profile name&amp;gt;/plugins&lt;/code&gt; and I suspect &lt;code&gt;/Applications/Firefox.app/Contents/MacOS/plugins&lt;/code&gt; would work too.&lt;/p&gt;

&lt;p&gt;So you can copy &lt;code&gt;Flash Player.plugin&lt;/code&gt;, &lt;code&gt;NP-PPC-Dir-Shockwave&lt;/code&gt; and &lt;code&gt;flashplayer.xpt&lt;/code&gt; to one of the Firefox specific folders and launch Firefox from Safari&apos;s Developer menu. Chrome starts up faster, though.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">xibgraph: Interface Builder overviews</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2010/06/19/xibgraph</id>
<updated>2010-06-19T16:17:13Z</updated>
<published>2010-06-19T16:17:13Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/xibgraph.html" />
<content type="html">&lt;p&gt;When putting together user interfaces with Interface Builder, you connect things together with bindings, actions and outlets and it&apos;s good. Understanding the result later on is a completely different matter. It can be time consuming and difficult to browse the objects inside one by one, trying to comprehend the whole. Even more so if you&apos;re trying to read someone else&apos;s work.&lt;/p&gt;

&lt;p&gt;Out of that frustration came &lt;a href=&quot;http://bitbucket.org/juri/xibgraph/&quot;&gt;xibgraph&lt;/a&gt;. It takes a XIB file and outputs the connections contained inside:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.juripakaste.fi/xibgraph1.png&quot; alt=&quot;Example xibgraph output&quot; title=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At the moment it supports bindings and actions. Outlets are next.&lt;/p&gt;

&lt;p&gt;xibgraph supports a couple of different output formats. JSON is supported out of the box and if you install &lt;a href=&quot;http://code.google.com/p/pydot/&quot;&gt;pydot&lt;/a&gt;, you get DOT, the format understood by &lt;a href=&quot;http://www.graphviz.org/&quot;&gt;Graphviz&lt;/a&gt; and &lt;a href=&quot;http://www.omnigroup.com/products/omnigraffle/&quot;&gt;OmniGraffle&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;It hasn&apos;t been tested on a particularly wide variety of XIBs, so it&apos;s very plausible it will produce wonky results or just outright refuse to work with your files. If so, patches and bug reports are welcome.&lt;/p&gt;

&lt;p&gt;xibgraph is MIT licensed and written in Python. It requires PyObjC (it seemed like the easiest way to get XPath support on OS X) and probably Python 2.6. Everything but the DOT support should work without additional requirements on OS X 10.6.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">hg-status-sections</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2010/06/04/hg-status-sections</id>
<updated>2010-06-04T17:14:13Z</updated>
<published>2010-06-04T17:14:13Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/hg-status-sections.html" />
<content type="html">&lt;p&gt;I usually use &lt;a href=&quot;http://bitbucket.org/snej/murky/wiki/Home&quot;&gt;Murky&lt;/a&gt;, &lt;a href=&quot;http://www.xsteve.at/prg/emacs_dvc/dvc.html&quot;&gt;dvc&lt;/a&gt; or some other shell for Mercurial. Not always though, for various reasons, and when running &lt;code&gt;hg status&lt;/code&gt; I&apos;m always frustrated when copy and pasting file names. &lt;code&gt;bzr&lt;/code&gt; provides neat, non-cluttered lines that can be copied whole to get a file name without a hassle, but &lt;code&gt;hg&lt;/code&gt; takes the traditional one-character prefix approach to status display and as a result makes you manually select a part of a line instead of just grabbing a whole line.&lt;/p&gt;

&lt;p&gt;So I wrote a small extension to help. Meet &lt;a href=&quot;http://bitbucket.org/juri/hg-status-sections/src&quot;&gt;hg-status-sections&lt;/a&gt;.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">A better @synthesize</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2010/05/22/better_synthesize</id>
<updated>2010-05-22T11:03:49Z</updated>
<published>2010-05-22T11:03:49Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/better_synthesize.html" />
<content type="html">&lt;p&gt;The biggest problem with Objective-C&apos;s &lt;code&gt;@synthesize&lt;/code&gt; directive for &lt;a href=&quot;http://developer.apple.com/mac/library/documentation/cocoa/conceptual/objectivec/articles/ocProperties.html&quot;&gt;properties&lt;/a&gt; is how difficult it&apos;s to augment the synthesized code. You often need to add logic to a property setter, but while you&apos;re adding it, you&apos;re losing the probably correct implementation Apple&apos;s code creates for property flags like &lt;code&gt;atomic&lt;/code&gt; and &lt;code&gt;retain&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At the moment, when you synthesize a &lt;code&gt;readwrite&lt;/code&gt; property called &lt;code&gt;foo&lt;/code&gt; you get a setter method called &lt;code&gt;setFoo&lt;/code&gt;. If you need to add logic around it, you can either store the value in a private property and add a public property with a different name or use a subclass. Both are a bit of a hassle. Usually I just end up writing my own method, including the logic for implementing the modifiers correctly.&lt;/p&gt;

&lt;p&gt;In an ideal world the language would support something like around/before/after methods in &lt;a href=&quot;http://en.wikipedia.org/wiki/Common_Lisp_Object_System&quot;&gt;CLOS&lt;/a&gt;, but those features are rare. There&apos;s a simple way &lt;code&gt;@synthesize&lt;/code&gt; could make things easier without requiring massive changes to the runtime. It could give you for both the getter and setter two methods. There would be the public methods they create in the current implementation, but there&apos;d also be methods with names like &lt;code&gt;__synthesized_property&lt;/code&gt; and &lt;code&gt;__synthesized_setProperty&lt;/code&gt;. The public methods would rely on the semi-private methods to actually implement all their logic. Then if you needed to add logic around the accessors, you could override the public methods and call the semi-private ones to get access to the synthesized accessor logic without jumping through hoops or risking getting the implementation wrong.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Block indentation in Emacs</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2010/03/08/emacs-block-indent</id>
<updated>2010-03-08T17:28:30Z</updated>
<published>2010-03-08T17:28:30Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/emacs-block-indent.html" />
<content type="html">&lt;p&gt;There are several small things Emacs could be doing to make it nicer to write code. One I was missing was making it possible to go with one press of the return key between braces in a C derived language from this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if (test) { }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if (test) {
   &amp;lt;-- insertion point here
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is, pressing return before the closing parentheses, brace or bracket should move the closing character two lines down, indent it properly, and move the insertion point to the new empty line in the middle and indent it property. The way TextMate does it.&lt;/p&gt;

&lt;p&gt;Here are a few of elisp functions to accomplish this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun char-isws (c)
  &quot;Is character c a whitespace character?&quot;
  (or (char-equal c ?\ )
      (char-equal c ?\t)
      (char-equal c ?\n)))

(defun line-next-non-ws ()
  &quot;Return the next non-whitespace character on the current line or nil.&quot;
  (let ((cc (char-after)))
    (if (and cc (char-isws cc))
        (save-excursion
          (if (re-search-forward &quot;[^[:space:]]&quot; (save-excursion     (end-of-line) (point)) t)
              (char-before)
            nil))
      cc)))

(defun newline-and-indent-extra-for-closing-paren ()
  &quot;Insert a newline and indent. If the next non-whitespace character is a closing paren, insert two newlines and indent the two  new lines correctly, placing the point on the first of the two new lines.&quot;
  (interactive)
  (let ((nc (line-next-non-ws)))
    (if (or (null nc)
            (not (= (char-syntax nc) ?))))
        (newline-and-indent)
      (progn
        (just-one-space)
        (newline-and-indent)
        (newline-and-indent)
        (previous-line)
        (indent-for-tab-command)))))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can bind return to &lt;code&gt;newline-and-indent-extra-for-closing-paren&lt;/code&gt; in a suitable language keymap. I&apos;ve been using this with &lt;code&gt;scala-mode&lt;/code&gt; and it works well there.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Exporting geolocation data from iPhoto with AppleScript</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2009/07/29/iphoto-geodata-applescript</id>
<updated>2009-07-29T19:04:21Z</updated>
<published>2009-07-29T19:04:21Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/iphoto-geodata-applescript.html" />
<content type="html">&lt;p&gt;I recently transferred all my photos to iPhoto. I &lt;a href=&quot;http://www.flickr.com/photos/juripakaste/&quot;&gt;share&lt;/a&gt; them on Flickr, but I&apos;ve been unhappy with iPhoto&apos;s built-in Flickr support &amp;#8212; it has an arbitrary 500 photo limit on web album size, it&apos;s crashy, it does weird synchronizations that take ages when combined with lots of large photos and a slow internet connection, it has multiple times failed to send all the full-resolution images &amp;#8212; so I&apos;ve been exploring alternatives. There&apos;s at least &lt;a href=&quot;http://connectedflow.com/flickrexport/&quot;&gt;FlickrExport&lt;/a&gt; and Flickr&apos;s own &lt;a href=&quot;http://www.flickr.com/tools/uploadr/&quot;&gt;Uploadr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Although the tools work, there&apos;s a downside compared to iPhoto&apos;s built-in Flickr support. iPhoto has wonderful geotagging support, as does Flickr, but iPhoto doesn&apos;t write the data to EXIF tags and that poses a problem for the tools. Uploadr reads just the files and so never sees the data, and apparently iPhoto doesn&apos;t provide the data to FlickrExport, either. The result is that Flickr won&apos;t know the locations of the photos.&lt;/p&gt;

&lt;p&gt;There&apos;s a way to work around this problem. The solution is AppleScript. iPhoto exports &lt;code&gt;photo&lt;/code&gt; objects that can tell you their location as set inside iPhoto. The downside to this approach is that it&apos;s AppleScript, but apparently the alternatives like Python or JSTalk aren&apos;t quite up to tasks like these without application support.&lt;/p&gt;

&lt;p&gt;This script will write the locations of the selected photos relies on &lt;a href=&quot;http://www.sno.phy.queensu.ca/~phil/exiftool/&quot;&gt;ExifTool&lt;/a&gt;. It will litter your photo directory with files ending with &lt;code&gt;_original&lt;/code&gt; that should contain the unmodified images. You should make sure the modified files are ok before deleting the originals. The usual caveats apply: I&apos;m no AppleScript expert and this has not been tested particularly rigorously. I&apos;d be careful especially if you don&apos;t live in the NE hemisphere. And you might want to reduce the number of dialogs. Do what you want with it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-- This applescript will geotag the selected photos with the
-- location information set in iPhoto.
--  
--   You must have exiftool installed; by default it&apos;s loaded from
-- /opt/local/bin, where MacPorts installs it from the package
-- p5-image-exiftool.
--
-- Author: Juri Pakaste (http://www.juripakaste.fi/)
--
-- Based on the Set Geo Data.scpt script by
-- Andrew Turner (http://highearthorbit.com)
-- 
property exifToolOriginal : &quot;_original&quot;
property exifToolPath : &quot;/opt/local/bin/exiftool&quot;

on extract_decimal(realnum)
   set res to realnum - (round realnum rounding down)
   res
end extract_decimal

on roundFloat(n, precision)
    set x to 10 ^ precision
    (((n * x) + 0.5) div 1) / x
end roundFloat

on d2s(degs)
    log &quot;enter d2s&quot;
    if the degs &amp;lt; 0 then
        set the degs to degs * -1
    end if

    set the degrees to round degs rounding down
    set the minssecs to extract_decimal(degs)

    log &quot;minssecs: &quot; &amp;amp; minssecs

    set the minssecs to minssecs * 60
    set the mins to round minssecs rounding down

    set the minssecs to extract_decimal(minssecs)
    log &quot;minssecs 2: &quot; &amp;amp; minssecs
    set the secs to minssecs * 60

    &quot;&quot; &amp;amp; degrees &amp;amp; &quot;,&quot; &amp;amp; mins &amp;amp; &quot;,&quot; &amp;amp; roundFloat(secs, 2)
end d2s

on exportCoords(image_file, lat, lng, alt)
    set the northSouth to &quot;N&quot;
    set the eastWest to &quot;E&quot;

    if the lat is less than 0 then
        set the northSouth to &quot;S&quot;
        set the lat to the lat * -1
    end if

    if the lng is less than 0 then
        set the eastWest to &quot;W&quot;
        set the lng to the lng * -1
    end if

    log &quot;calling d2s on &quot; &amp;amp; lat
    set the latstr to my d2s(lat)
    set the lngstr to my d2s(lng)

    set exifCommand to exifToolPath &amp;amp; &quot; -GPSMapDatum=WGS-84     -gps:GPSLatitude=&apos;&quot; &amp;amp; latstr &amp;amp; &quot;&apos; -gps:GPSLatitudeRef=&apos;&quot; &amp;amp; northSouth     ¬
        &amp;amp; &quot;&apos; -gps:GPSLongitude=&apos;&quot; &amp;amp; lngstr &amp;amp; &quot;&apos;     -gps:GPSLongitudeRef=&apos;&quot; &amp;amp; eastWest ¬
        &amp;amp; &quot;&apos; -xmp:GPSLatitude=&apos;&quot; &amp;amp; latstr &amp;amp; northSouth &amp;amp; &quot;&apos;     -xmp:GPSLongitude=&apos;&quot; &amp;amp; lngstr &amp;amp; eastWest &amp;amp; &quot;&apos;     -xmp:GPSMapDatum=&apos;WGS-84&apos;&quot; &amp;amp; &quot; -xmp:GPSVersionID=&apos;2.2.0.0&apos;&quot; &amp;amp; &quot; &quot; &amp;amp; quoted form of image_file
    display dialog of (&quot;running: &quot; &amp;amp; exifCommand)
    set output to do shell script exifCommand
    display dialog of output
    --do shell script &quot;rm &apos;&quot; &amp;amp; image_file &amp;amp; &quot;&apos;&quot; &amp;amp;     exifToolOriginal    
end exportCoords

tell application &quot;iPhoto&quot;
    activate
    try
        copy (my selected_images()) to these_images
        if these_images is false or (the count of     these_images) is 0 then ¬
            error &quot;Please select one or more images.&quot;

        repeat with i from 1 to the count of these_images
            set this_photo to item i of these_images
            tell this_photo
                set the image_file to the image path
                set lat to the latitude
                set lng to the longitude
                set alt to the altitude
            end tell

            if lat &amp;lt; 90.1 and lng &amp;lt; 180.1 then
                my exportCoords(image_file, lat, lng,     alt)
            else
                display alert (&quot;No location set for &quot;     &amp;amp; name of this_photo)
            end if

            log &quot;read image, lat: &quot; &amp;amp; lat &amp;amp; &quot;, lng: &quot; &amp;amp;     lng

        end repeat
        display dialog &quot;Geo Exif write complete.&quot;
    on error error_message number error_number
        if the error_number is not -128 then
            display dialog of (&quot;failed on: &quot; &amp;amp; image_file)
            display dialog error_message buttons     {&quot;Cancel&quot;} default button 1
        end if
    end try
end tell


on selected_images()
    tell application &quot;iPhoto&quot;
        try
            -- get selection
            set these_items to the selection
            -- check for single album selected
            if the class of item 1 of these_items is album     then error
            -- return the list of selected photos
            return these_items
        on error
            return false
        end try
    end tell
end selected_images
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Update (2010-02-28)&lt;/strong&gt;: Thank you to &lt;a href=&quot;http://twitter.com/simonmark/&quot;&gt;@simonmark&lt;/a&gt; on Twitter, who &lt;a href=&quot;http://twitter.com/simonmark/status/9758717258&quot;&gt;pointed out&lt;/a&gt; the script had some issues. My version broke if file names had single quotes in them and Simon&apos;s version broke with double quotes (admittedly probably rarer in file names.) I was going to leave it as it was, but found the &lt;code&gt;quoted form&lt;/code&gt; method of &lt;code&gt;text&lt;/code&gt; objects in &lt;a href=&quot;http://developer.apple.com/mac/library/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html&quot;&gt;AppleScript Language Guide&lt;/a&gt; which, assuming it works correctly, should make the script always work properly (at least in terms of file name handling.) I also copied Simon&apos;s better error display code and replaced the &lt;code&gt;extract_decimal&lt;/code&gt; implementation with something that isn&apos;t quite as silly as my previous version was.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update (2010-06-02)&lt;/strong&gt;: I set up a Bitbucket
&lt;a href=&quot;http://bitbucket.org/juri/iphoto-scripts/src&quot;&gt;repository&lt;/a&gt; for this
and other scripts I&apos;ve written for iPhoto.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Announcing Chipmunk Backup</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2009/02/27/chipmunk-backup</id>
<updated>2009-02-27T16:31:01Z</updated>
<published>2009-02-27T16:31:01Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/chipmunk-backup.html" />
<content type="html">&lt;p&gt;I put up on Launchpad a backup utility I wrote called &lt;a href=&quot;https://launchpad.net/chipmunk-backup&quot;&gt;Chipmunk Backup&lt;/a&gt;. It&apos;s not extremely configurable nor does it have a huge set of features. It&apos;s a simple tool for maintaining a number of GnuPG encrypted full backups of a directory in a remote, rsync-accessible location.&lt;/p&gt;

&lt;p&gt;There&apos;s no ready to download archive, but checking out &lt;code&gt;lp:chipmunk-backup&lt;/code&gt; with &lt;a href=&quot;http://bazaar-vcs.org/&quot;&gt;bzr&lt;/a&gt; should give you a working version.&lt;/p&gt;

&lt;p&gt;It&apos;s written in &lt;a href=&quot;http://www.plt-scheme.org/&quot;&gt;PLT Scheme&lt;/a&gt; and is known to work with version 4.1.4.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Emacs tips: Navigate CamelCase words</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2009/01/06/emacs-tip</id>
<updated>2009-01-06T14:26:02Z</updated>
<published>2009-01-06T14:26:02Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/emacs-tip.html" />
<content type="html">&lt;p&gt;Emacs tip #0: Always search &lt;a href=&quot;http://www.emacswiki.org/&quot;&gt;EmacsWiki&lt;/a&gt; when you think you might need something.&lt;/p&gt;

&lt;p&gt;Emacs tip #1: To navigate studlyCapped words, &lt;code&gt;M-x c-subword-mode&lt;/code&gt;, as found on the &lt;a href=&quot;http://www.emacswiki.org/emacs/CamelCase&quot;&gt;CamelCase page&lt;/a&gt;. I had to add the following lines to my &lt;code&gt;.emacs&lt;/code&gt; to get it work with &lt;code&gt;C-left&lt;/code&gt;/&lt;code&gt;C-right&lt;/code&gt;, &lt;code&gt;M-b&lt;/code&gt;/&lt;code&gt;M-f&lt;/code&gt; worked right out of the box:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-key global-map [(control right)] &apos;forward-word)
(define-key global-map [(control left)] &apos;backward-word)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Before that, they were bound to the &lt;code&gt;-nomark&lt;/code&gt; variants.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Inline admin forms with admin site links in Django</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2008/12/23/django-admin-inline-link</id>
<updated>2008-12-23T14:52:49Z</updated>
<published>2008-12-23T14:52:49Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/django-admin-inline-link.html" />
<content type="html">&lt;p&gt;I have a somewhat difficult relationship with &lt;a href=&quot;http://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt;&apos;s admin site. It&apos;s a very useful feature, but I haven&apos;t really done enough with it to know when I&apos;m going to hit a wall, if that wall&apos;s in the code or in my understanding, and how hard it&apos;s going to be to climb over the wall.&lt;/p&gt;

&lt;p&gt;This time I wanted to have &lt;a href=&quot;http://docs.djangoproject.com/en/dev/ref/contrib/admin/#inlinemodeladmin-objects&quot;&gt;inline admin forms&lt;/a&gt;, except that I didn&apos;t actually want to have the forms there, I just wanted to have links to the objects &amp;#8212; and not their views on the actual site, but on the admin site. As far as I can tell, there&apos;s no built-in support for this.&lt;/p&gt;

&lt;p&gt;According to the admin docs, there are two subclasses of &lt;code&gt;InlineModelAdmin&lt;/code&gt;: &lt;code&gt;TabularInline&lt;/code&gt; and &lt;code&gt;StackedInline&lt;/code&gt;. Looking at &lt;a href=&quot;http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py?rev=9383#L804&quot;&gt;django/contrib/admin/options.py&lt;/a&gt; confirms this. And as the docs say, the only difference is the template they use. The stacked version comes pretty close when we add all the fields to an &lt;code&gt;InlineModelAdmin&lt;/code&gt; subclass&apos;s exclude array, but it doesn&apos;t have the link.&lt;/p&gt;

&lt;p&gt;To solve this we first create a new subclass:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class LinkedInline(admin.options.InlineModelAdmin):
    template = &quot;admin/edit_inline/linked.html&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you want to create inline links to a model, you subclass this new &lt;code&gt;LinkedInline&lt;/code&gt; class. So to use a slightly contrived example, if we have a Flight with Passengers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class PassengerInline(LinkedInline):
    model = models.Passenger
    extra = 0
    exclude = [ &quot;name&quot;, &quot;sex&quot; ] # etc

class FlightAdmin(admin.ModelAdmin):
    inlines = [ PassengerInline ]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And yes, we have to exclude all the fields explicitly: an empty &lt;code&gt;fields&lt;/code&gt; tuple or list is ignored.&lt;/p&gt;

&lt;p&gt;The new template is easiest to create by cutting down aggressively the stacked template. Like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{% load i18n %}
&amp;lt;div class=&quot;inline-group&quot;&amp;gt;
  &amp;lt;h2&amp;gt;{{ inline_admin_formset.opts.verbose_name_plural|title}}&amp;lt;/h2&amp;gt;
{{ inline_admin_formset.formset.management_form }}
{{ inline_admin_formset.formset.non_form_errors }}

{% for inline_admin_form in inline_admin_formset %}
&amp;lt;div class=&quot;inline-related {% if forloop.last %}last-related{% endif %}&quot;&amp;gt;
  &amp;lt;h3&amp;gt;&amp;lt;b&amp;gt;{{ inline_admin_formset.opts.verbose_name|title }}:&amp;lt;/b&amp;gt;&amp;amp;nbsp;{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %} #{{ forloop.counter }}{% endif %}
    {% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}&amp;lt;span class=&quot;delete&quot;&amp;gt;{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}&amp;lt;/span&amp;gt;{% endif %}
  &amp;lt;/h3&amp;gt;
  {{ inline_admin_form.pk_field.field }}
  {{ inline_admin_form.fk_field.field }}
&amp;lt;/div&amp;gt;
{% endfor %}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The primary/foreign key fields are necessary to keep Django happy.&lt;/p&gt;

&lt;p&gt;The result looks about right, it just lacks the links. It seems that Django doesn&apos;t give the template all the information we need to make them work: there&apos;s &lt;code&gt;root_path&lt;/code&gt; that gives us &lt;code&gt;/admin/&lt;/code&gt;, &lt;code&gt;app_label&lt;/code&gt; contains the application&apos;s name and &lt;code&gt;inline_admin_form.original.id&lt;/code&gt; contains the id of the inline object. What is lacking is the path component that names the model. I don&apos;t think it&apos;s available by default (is there a clean way to ask Django what&apos;s available in a template&apos;s context?), so we need to add it. Amend &lt;code&gt;LinkedInline&lt;/code&gt; to look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class LinkedInline(admin.options.InlineModelAdmin):
    template = &quot;admin/edit_inline/linked.html&quot;
    admin_model_path = None

    def __init__(self, *args):
        super(LinkedInline, self).__init__(*args)
        if self.admin_model_path is None:
            self.admin_model_path = self.model.__name__.lower()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now &lt;code&gt;inline_admin_formset.opts.admin_model_path&lt;/code&gt; will be bound to the lowercase name of the inline object&apos;s model, which is what the admin site uses in its paths.&lt;/p&gt;

&lt;p&gt;With this, we can now replace the &lt;code&gt;inline-related&lt;/code&gt; &lt;code&gt;div&lt;/code&gt; in the template with this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;inline-related {% if forloop.last %}last-related{%  endif %}&quot;&amp;gt;
  &amp;lt;h3&amp;gt;&amp;lt;b&amp;gt;{{ inline_admin_formset.opts.verbose_name|title  }}:&amp;lt;/b&amp;gt;&amp;amp;nbsp;&amp;lt;a href=&quot;{{ root_path }}{{ app_label }}/{{ inline_admin_formset.opts.admin_model_path }}/{{ inline_admin_form.original.id }}/&quot;&amp;gt;{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %} #{{ forloop.counter }}{% endif %}&amp;lt;/a&amp;gt;
    {% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}&amp;lt;span class=&quot;delete&quot;&amp;gt;{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}&amp;lt;/span&amp;gt;{% endif %}
  &amp;lt;/h3&amp;gt;
  {{ inline_admin_form.pk_field.field }}
  {{ inline_admin_form.fk_field.field }}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&apos;s it. Now Flights get links to Passengers without big forms cluttering up the page.&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">iPhone shuffle</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2008/11/21/iphone_shuffle</id>
<updated>2008-11-21T18:31:33Z</updated>
<published>2008-11-21T18:31:33Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/iphone_shuffle.html" />
<content type="html">&lt;p&gt;These days I use an iPhone as my mobile music device. I have a bit over 1800 songs on it. I usually use shuffle and had it stuck in a weird state a couple of weeks ago &amp;#8212; it was &lt;a href=&quot;http://www.last.fm/music/The+Roots/_/Act+Too+(The+Love+of+My+Life)+(feat.+Common)&quot;&gt;constantly&lt;/a&gt; &lt;a href=&quot;http://www.last.fm/music/Kanye+West/_/Addiction&quot;&gt;playing&lt;/a&gt; &lt;a href=&quot;http://www.last.fm/music/Kanye+West/_/Addiction&quot;&gt;me&lt;/a&gt; &lt;a href=&quot;http://www.last.fm/music/Marvin+Gaye/_/After+the+Dance+%28instrumental%29&quot;&gt;just&lt;/a&gt; &lt;a href=&quot;http://www.last.fm/music/The+Roots/_/Adrenaline%21&quot;&gt;a&lt;/a&gt; &lt;a href=&quot;http://www.last.fm/music/Jos%C3%A9+Padilla/_/Adi%C3%B3s+Ayer&quot;&gt;few&lt;/a&gt; &lt;a href=&quot;http://www.last.fm/music/4hero/_/The+Action+%28Shawn+J+Period+remix%29&quot;&gt;tracks&lt;/a&gt;. I usually listen for just half an hour to an hour at a time, so I don&apos;t know if it would have started looping or what, but those were basically always there for a week&apos;s worth of commutes. I finally restarted the phone and that seemed to help, but what do you know, a couple of weeks, several restarts and one operating system upgrade later, it&apos;s again playing me exactly the same tracks.&lt;/p&gt;

&lt;p&gt;As much as I love the The Roots, honestly, at this points Adrenaline!&apos;s &quot;Once a-again, once a-gain...&quot; start makes me mostly think &quot;once again indeed.&quot;&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Crashes with NSURLConnection</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2008/10/04/nsurlconnection_start_crash</id>
<updated>2008-10-04T14:30:53Z</updated>
<published>2008-10-04T14:30:53Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/nsurlconnection_start_crash.html" />
<content type="html">&lt;p&gt;Speaking of Cocoa (and iPhone) programming, for a change.&lt;/p&gt;

&lt;p&gt;Having trouble with spurious EXC_BAD_ACCESS crashes when using NSURLConnection? NSZombie giving you not very clear messages about [Not A Type retain], pointing to an address that malloc_history says has been allocated somewhere with only framework code in the call stack? See &lt;a href=&quot;http://amromousa.com/2008/08/27/nsurlconnection-timeoutconnection-amdev-woes/&quot;&gt;Amro Mousa&apos;s blog entry&lt;/a&gt; about the subject.&lt;/p&gt;

&lt;p&gt;In a nutshell, don&apos;t send the start message to a NSURLConnection object you&apos;ve initialized with a +connectionWithRequest:delegate: or -initWithRequest:delegate:. It&apos;ll break stuff.&lt;/p&gt;

&lt;p&gt;Apple, how about a warning about this in the docs? The docs for -start say &quot;Causes the receiver to begin loading data, if it has not already.&quot;, not &quot;Will break your program and make you waste uncounted hours debugging if receiver has already started.&quot; Or how about preventing this in the code? Is there some scenario where you&apos;d want to call start after the object has already started?&lt;/p&gt;
</content>
</entry>

<entry>
<title type="html">Various Python related things</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2008/09/18/di_python_stuff</id>
<updated>2008-09-18T15:14:52Z</updated>
<published>2008-09-18T15:14:52Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/di_python_stuff.html" />
<content type="html">&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://pymag.phparch.com/&quot;&gt;Python Magazine&lt;/a&gt; published my article &quot;Using Dependency Injection in Python&quot; in their &lt;a href=&quot;http://pymag.phparch.com/c/issue/view/79&quot;&gt;August issue&lt;/a&gt;. &lt;a href=&quot;http://blog.doughellmann.com/&quot;&gt;Doug Hellman&lt;/a&gt; saw &lt;a href=&quot;http://www.juripakaste.fi/blog/dependency_injection.html&quot;&gt;my blog entry about DI&lt;/a&gt; when I was switching web hosting and managed to repost old stuff to Planet Python, contacted me to ask if I wanted to expand on it a bit, I said yes, and now I&apos;ve been published. Which is nice. I basically argue in the article that dependency injection is a good idea and you don&apos;t need to buy into a framework to get many of the benefits and provide some examples on how to do it. Which seems kind of apropos, seeing as there&apos;s yet another &lt;a href=&quot;http://www.traceback.org/2008/09/08/ann-snake-guice-preview-a-dependency-injection-framework/&quot;&gt;new contestant&lt;/a&gt; in that area.&lt;/li&gt;
&lt;li&gt;I was hacking on something I wrote in Python recently and was doing it in a pretty heavily dependency injected manner, writing tests as I was going along. It came to me that one really basic, really nice thing about Python that isn&apos;t discussed all that much is that callables are duck typed and there are multiple choices on how to implement them. When you write a function that takes as a parameter something it calls to acquire values it doesn&apos;t have to care what the thing it&apos;s been given actually is. It can be a function, a callable, a bound method, a constructor, a lambda expression or even a generator. The caller doesn&apos;t have to care. It&apos;s not a language feature that&apos;s easy to fit in a bullet point or to appreciate without using it, but it is useful.&lt;/li&gt;
&lt;li&gt;I was excited to see class decorators are coming in Python 2.6. Then I realized I can&apos;t remember what I wanted to use them for when I was really frustrated by their absence, but still, it&apos;s good. I always found their absence rather puzzling.&lt;/li&gt;
&lt;/ul&gt;
</content>
</entry>

<entry>
<title type="html">Flow 08: Saturday and Sunday</title>
<category term="" />
<id>http://juripakaste.fi/cgi/pyblosxom.cgi/2008/08/18/flow08_saturday_sunday</id>
<updated>2008-08-18T20:04:36Z</updated>
<published>2008-08-18T20:04:36Z</published>
<link rel="alternate" type="text/html" href="http://juripakaste.fi/cgi/pyblosxom.cgi/flow08_saturday_sunday.html" />
<content type="html">&lt;p&gt;On Saturday, it was raining cats and dogs. We were appropriately equipped and sniggered at the people in trainers etc trying to dodge the puddles. However, didn&apos;t see too many acts &amp;#8212; saw a bit of &lt;a href=&quot;http://www.myspace.com/sebastientellier&quot;&gt;Sébastien Tellier&lt;/a&gt;, but decided the crowds were too much and went to find some food (which was excellent and at 25 € for a three course vegetarian menu pretty good value.)&lt;/p&gt;

&lt;p&gt;Next up on our schedule was &lt;a href=&quot;http://www.csshurts.com/&quot;&gt;CSS&lt;/a&gt;, which was pretty good. For some reason, it has never quite clicked for me, but still, they were busy as hell and obviously having fun.&lt;/p&gt;

&lt;p&gt;And finally, &lt;a href=&quot;http://www.theroots.com/&quot;&gt;The Roots&lt;/a&gt;. What a great show. No bling, no diva manners, just excellent hip hop with a surprising amount of jazz thrown in, just like on their early albums. And an incredibly diverse band, with &lt;a href=&quot;http://en.wikipedia.org/wiki/Captain_Kirk_Douglas&quot;&gt;Captain Kirk&lt;/a&gt; shredding his guitar and Tuba Gooding Jr on &lt;a href=&quot;http://en.wikipedia.org/wiki/Sousaphone&quot;&gt;sousaphone&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Saturday was the only day it really felt like there were too many people stuffed into too small a space. Maybe it was the rain, maybe it was the fact that it was sold out, even though I don&apos;t think the other two days were that far behind.&lt;/p&gt;

&lt;p&gt;On Sunday we were definitely starting to feel old and tired. It&apos;s surprising how tiring three days of festival gets, even without excessive drinking. Maybe I&apos;m just too old. While eating on Saturday, I had the idea that they really should offer a show and dinner version of the festival; they already have an excellent restaurant on board, now just stretch out the dinner experience a bit and place the restaurant in a suitable location, and hey, the middle aged among us could be nice and comfy while checking out the gigs. And I really think they should have put the restaurant on the &lt;a href=&quot;http://www.flickr.com/photos/juripakaste/2767663750/in/set-72157606759737007/&quot;&gt;roof&lt;/a&gt; of the newer (if it is newer, the black one) gasometer.&lt;/p&gt;

&lt;p&gt;We caught a glimpse of &lt;a href=&quot;http://www.myspace.com/astrocancaravan&quot;&gt;Astro Can Caravan&lt;/a&gt;, who had the weirdo jazz thing pretty well covered. Next up was &lt;a href=&quot;http://www.thefivecornersquintet.com/&quot;&gt;The Five Corners Quintet&lt;/a&gt;, whose retro jazz was excellent as always. After that, we first checked out &lt;a href=&quot;http://www.plutonium74.net/&quot;&gt;Plutonium 74&lt;/a&gt;, and had enough after one and a half songs. We listened to the first two or three songs from Señor Coconut and while their version of Daft Punk&apos;s Around the World wasn&apos;t horrible it wasn&apos;t nowhere near as good as Christian Prommer&apos;s on Friday, and by the time they hit Eurythmics&apos; Sweet Dreams, we decided we had had enough of that too.&lt;/p&gt;

&lt;p&gt;The next act we saw was &lt;a href=&quot;http://www.myspace.com/josejamesquartet&quot;&gt;José James&lt;/a&gt; who was one of the high points of the festival. He did a surprisingly jazzy gig and the crowd appreciated. After his gig, we listened for a couple of songs by &lt;a href=&quot;http://www.myspace.com/cutcopy&quot;&gt;Cut Copy&lt;/a&gt;, who really revealed themselves to be very summery party pop. Loud summery party pop. Their album In Ghost Colors was decent but I didn&apos;t get into it all that much, but they were better live. However, we were just too tired at that point and after a while headed home.&lt;/p&gt;
</content>
</entry>
</feed>

