<?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>Reliably Broken &#187; Blog</title>
	<atom:link href="http://reliablybroken.com/b/category/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://reliablybroken.com/b</link>
	<description>It&#039;s a blog: let&#039;s do funch!</description>
	<lastBuildDate>Thu, 01 Dec 2011 21:27:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>SharpZipLib and Mac redux</title>
		<link>http://reliablybroken.com/b/2011/12/sharpziplib-and-mac-redux/</link>
		<comments>http://reliablybroken.com/b/2011/12/sharpziplib-and-mac-redux/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 21:21:00 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=706</guid>
		<description><![CDATA[I wrote a blog about generating Mac-compatible zip files with SharpZipLib, the conclusion of which was to disable Zip64 compatibility. It was wrong, wrong I tell you. The better solution is to just set the size of each file you add to the archive. That way you can keep Zip64 compatibility and Mac compatibility. I [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote a blog about <a href="http://reliablybroken.com/b/2011/11/sharpziplib-and-mac-os-x/">generating Mac-compatible zip files with SharpZipLib</a>, the conclusion of which was to disable Zip64 compatibility. It was wrong, <em>wrong</em> I tell you.</p>

<p>The better solution is to just set the size of each file you add to the archive. That way you can keep Zip64 compatibility and Mac compatibility.</p>

<p>I owe this solution to the excellent SharpZipLib forum, <a href="http://community.sharpdevelop.net/forums/p/4982/18649.aspx#18649">which covered this problem a while ago</a>, but which I missed when I wrote the earlier blog.</p>

<p>Here&#8217;s an updated version of the zip tool in C# that makes Macs happy without annoying anyone else:</p>

<pre><code>using System;
using System.IO;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;


public class ZipTool
{
    public static void Main(string[] args)
    {
        if (args.Length != 2) {
            Console.WriteLine("Usage: ziptool &lt;input file&gt; &lt;output file&gt;");
            return;
        }

        using (ZipOutputStream zipout = new ZipOutputStream(File.Create(args[1]))) {
            byte[] buffer = new byte[4096];
            string filename = args[0];

            zipout.SetLevel(9);

            //  Set the size before adding it to the archive, to make your
            //  Mac-loving hippy friends happy.
            ZipEntry entry = new ZipEntry(Path.GetFileName(filename));
            FileInfo info = new FileInfo(filename);
            entry.DateTime = info.LastWriteTime;
            entry.Size = info.Length;
            zipout.PutNextEntry(entry);

            using (FileStream fs = File.OpenRead(filename)) {
                int sourceBytes;
                do {
                    sourceBytes = fs.Read(buffer, 0, buffer.Length);
                    zipout.Write(buffer, 0, sourceBytes);
                } while (sourceBytes &gt; 0);
            }

            zipout.Finish();
            zipout.Close();
        }
    }
}
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/12/sharpziplib-and-mac-redux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SharpZipLib and Mac OS X</title>
		<link>http://reliablybroken.com/b/2011/11/sharpziplib-and-mac-os-x/</link>
		<comments>http://reliablybroken.com/b/2011/11/sharpziplib-and-mac-os-x/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 22:50:45 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[macports]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=699</guid>
		<description><![CDATA[TL;DR When creating zip archives with SharpZipLib disable Zip64 format if you care about Mac compatibility. Extra TL;DR When creating zip archives with SharpZipLib make sure you set the file size, disabling Zip64 is neither here nor there. A project I am working on sources a zip archive from a Web service, extracts the XML [...]]]></description>
			<content:encoded><![CDATA[<p>TL;DR When creating zip archives with SharpZipLib disable Zip64 format if you care about Mac compatibility.</p>

<p>Extra TL;DR <a href="http://reliablybroken.com/b/2011/12/sharpziplib-and-mac-redux/">When creating zip archives with SharpZipLib make sure you set the file size</a>, disabling Zip64 is neither here nor there.</p>

<p>A project I am working on sources a zip archive from a Web service, extracts the XML file from the zip and then does silly amounts of processing of the data in that XML to produce a new XML file which is returned to the user.</p>

<p>But the sourced zip archive cannot be opened using <a href="http://docs.python.org/library/zipfile.html">Python&#8217;s zipfile module</a>, and when saved on a Mac the archive cannot be opened using the built-in Archive Utility.app. If one double-clicks the zip, Archive Utility.app just compresses it again and sticks &#8220;.cpgz&#8221; on the end of the file name.</p>

<p>Fortunately the developer of the Web service is very helpful (the service is written in C# and runs on Windows) and although he didn&#8217;t know why Macs were having problems (the built-in Windows zip tool can handle the archive fine) he showed me the code that creates the zip file.</p>

<p>Turns out they were using <a href="http://www.icsharpcode.net/opensource/sharpziplib/">SharpZipLib, an open-source library for C#</a>. And it turns out SharpZipLib creates archives using <a href="http://en.wikipedia.org/wiki/ZIP_(file_format)#ZIP64">Zip64 format</a> by default.</p>

<p>The fix was to disable Zip64 when creating the archive. Here&#8217;s a trivial command-line program that creates a zip and disables Zip64 for Mac compatibility:</p>

<pre><code>using System;
using System.IO;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;


public class ZipTool
{
    public static void Main(string[] args)
    {
        if (args.Length != 2) {
            Console.WriteLine("Usage: ziptool &lt;input file&gt; &lt;output file&gt;");
            return;
        }

        using (ZipOutputStream zipout = new ZipOutputStream(File.Create(args[1]))) {
            byte[] buffer = new byte[4096];
            string filename = args[0];

            zipout.SetLevel(9);

            // Disable Zip64 for Mac compatibility
            zipout.UseZip64 = UseZip64.Off;

            ZipEntry entry = new ZipEntry(Path.GetFileName(filename));            
            entry.DateTime = File.GetLastWriteTime(filename);
            zipout.PutNextEntry(entry);

            using (FileStream fs = File.OpenRead(filename)) {
                int sourceBytes;
                do {
                    sourceBytes = fs.Read(buffer, 0, buffer.Length);
                    zipout.Write(buffer, 0, sourceBytes);
                } while (sourceBytes &gt; 0);
            }

            zipout.Finish();
            zipout.Close();
        }
    }
}
</code></pre>

<p>The disadvantage of disabling Zip64 is you cannot create archives larger than 4 gigabytes, nor can you add files larger than 4 gigabytes before compression.</p>

<p>The advantage of disabling Zip64 is you make me and all my Mac-using hippy friends happy. In concrete terms, disabling Zip64 makes it more likely I will buy you a drink.</p>

<p>Hi Gaston!</p>

<p>Also many thanks to the maintainer of NAnt in <a href="http://www.macports.org/">MacPorts</a>, who responded to <a href="http://trac.macports.org/ticket/32097">my bug report</a> and pushed an updated NAnt to MacPorts extremely quickly. Although SharpZipLib doesn&#8217;t officially support <a href="http://www.mono-project.com/">Mono</a>, it builds without a hitch using the &#8220;build-net-2.0&#8243; target if you hack the <code>SharpZlib.build</code> NAnt script like so:</p>

<pre><code>&lt;target name="build-mono-2.0" &gt;
    &lt;call target="build-net-2.0" /&gt;
    &lt;!--&lt;fail message="Dont know how to build for Mono 2.0." /&gt;--&gt;
&lt;/target&gt;
</code></pre>

<p>Also thanks to the Mono project! Saved me having to fire up a Windows virtual machine to figure out this problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/11/sharpziplib-and-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Widths &amp; Heights with xlwt + Python</title>
		<link>http://reliablybroken.com/b/2011/10/widths-heights-with-xlwt-python/</link>
		<comments>http://reliablybroken.com/b/2011/10/widths-heights-with-xlwt-python/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 15:47:43 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=693</guid>
		<description><![CDATA[This article about using xlwt to generate Excel in Python reminded me I needed to see exactly how to set column widths (the xlwt documentation doesn&#8217;t cover it). Let&#8217;s create a new Excel workbook and add a sheet: &#62;&#62;&#62; import xlwt &#62;&#62;&#62; book = xlwt.Workbook(encoding='utf-8') &#62;&#62;&#62; sheet = book.add_sheet('sheeeeeet') We need to get a column [...]]]></description>
			<content:encoded><![CDATA[<p>This <a href="http://www.youlikeprogramming.com/2011/04/generating-excel-documents-with-the-xlwt-python-library-with-examples/trackback/">article about using xlwt to generate Excel</a> in <a href="http://www.python.org/">Python</a> reminded me I needed to see exactly how to set column widths (the <a href="https://secure.simplistix.co.uk/svn/xlwt/trunk/xlwt/doc/xlwt.html">xlwt documentation</a> doesn&#8217;t cover it).</p>

<p>Let&#8217;s create a new <a href="http://office.microsoft.com/en-us/excel">Excel</a> workbook and add a sheet:</p>

<pre><code>&gt;&gt;&gt; import xlwt
&gt;&gt;&gt; book = xlwt.Workbook(encoding='utf-8')
&gt;&gt;&gt; sheet = book.add_sheet('sheeeeeet')
</code></pre>

<p>We need to get a column in order to set its width. You do that by call <code>col()</code> on the sheet, passing the column&#8217;s index as the only argument (or <code>row()</code> for accessing rows):</p>

<pre><code>&gt;&gt;&gt; sheet.col(0)    # First column
&lt;xlwt.Column.Column object at 0x10b2a6190&gt;
&gt;&gt;&gt; sheet.row(2)    # Third row
&lt;xlwt.Row.Row object at 0x10b2a7050&gt;
</code></pre>

<p>The index is zero-based. You can fetch a column even if you have not written to any cell in that column (this applies equally to rows).</p>

<p>Columns have a property for setting the width. The value is an integer specifying the size measured in 1/256 of the width of the character &#8217;0&#8242; as it appears in the sheet&#8217;s default font. xlwt creates columns with a default width of 2962, roughly equivalent to 11 characters wide.</p>

<pre><code>&gt;&gt;&gt; first_col = sheet.col(0)
&gt;&gt;&gt; first_col.width = 256 * 20              # 20 characters wide (-ish)
&gt;&gt;&gt; first_col.width
5120
</code></pre>

<p>For rows, the height is determined by the style applied to the row or any cell in the row. <em>(In fact rows also have a property called <code>height</code> but it doesn&#8217;t do what you want.)</em> To set the height of the row itself, create a new style with a font height:</p>

<pre><code>&gt;&gt;&gt; tall_style = xlwt.easyxf('font:height 720;') # 36pt
&gt;&gt;&gt; first_row = sheet.row(0)
&gt;&gt;&gt; first_row.set_style(tall_style)
</code></pre>

<p>Setting the style on the row does not change the style of the cells in that row.</p>

<p>There is no obvious way to set a default width and height for all columns and rows. An instance of <code>xlwt.Worksheet.Worksheet</code> has properties for <code>col_default_width</code> and <code>row_default_height</code> but changing those does not actually change the defaults.</p>

<p>The problem is that new columns are always created with an explicit width, while rows take their height from the style information.</p>

<p>My first attempt at setting defaults set the width on every column and the height on every row. It works, but <a href="http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP005199291.aspx">creates 65,536 unnecessary empty row objects</a>.</p>

<p>A slightly better approach is to set the width on every column and to set the font height on the default style record in the workbook:</p>

<pre><code>import itertools
import xlwt

book = xlwt.Workbook(encoding='utf-8')
sheet = book.add_sheet('sheeeeeet')

col_width = 256 * 20                        # 20 characters wide

try:
    for i in itertools.count():
        sheet.col(i).width = col_width
except ValueError:
    pass

default_book_style = book.default_style
default_book_style.font.height = 20 * 36    # 36pt

book.save('example.xls')
</code></pre>

<p>Here I used <code>itertools.count()</code> and wrapped the loop in a try block so I can forget exactly how many columns are permitted. When the loop tries to access a bad index it will throw <code>ValueError</code> and the loop will exit.</p>

<p>You mustn&#8217;t replace the default style on an instance of xlwt.Workbook.Workbook, you have to update the property of the existing style (to ensure you are changing the <em>first</em> style record). Unfortunately there is no way to set a default column width (as of xlwt version 0.7.2) so the brute force method of setting every column will have to do &#8211; it isn&#8217;t so bad since there are only 256 columns.</p>

<p>Talking of widths and heights, have you heard <a href="http://www.youtube.com/watch?v=2WtqQ6X2F8Q">&#8220;Widths &amp; Heights&#8221;</a> by <a href="http://magicarm.co.uk/">Magic Arm</a>? Is good.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/10/widths-heights-with-xlwt-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Date variables in InDesign</title>
		<link>http://reliablybroken.com/b/2011/09/indesign-variable-formatting/</link>
		<comments>http://reliablybroken.com/b/2011/09/indesign-variable-formatting/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 20:11:24 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[indesign]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=679</guid>
		<description><![CDATA[Interesting InDesign problem: the format for a modification date variable changes per document. (This post describes a problem using Adobe InDesign CS4 but applies just as well to CS5 and CS5 and a half.) Suppose you have a text frame containing the file modification date variable, created using Type → Text Variables → Insert Variable [...]]]></description>
			<content:encoded><![CDATA[<p>Interesting <a href="http://www.adobe.com/products/indesign.html">InDesign</a> problem: the format for a modification date variable changes per document.</p>

<p><em>(This post describes a problem using Adobe InDesign CS4 but applies just as well to CS5 and CS5 and a half.)</em></p>

<p>Suppose you have a text frame containing the <a href="http://help.adobe.com/en_US/indesign/cs/using/WS6A9BE096-77B2-4721-9736-797C4912B6C9a.html">file modification date variable</a>, created using <em>Type</em> → <em>Text Variables</em> → <em>Insert Variable</em> → <em>Modification Date</em>, displays as &#8220;14 September 2011 7:50 PM&#8221; (on my system). Now open an existing document that was created on a different system and copy and paste the text frame containing the date variable. But depending on what system created the other document the date displays using a different format, e.g as &#8220;September 14, 2011 19:50&#8243;.</p>

<p>It appears that the date format is determined by the document in which it is placed, rather than by the date format in use when the variable was created.</p>

<p>Workaround: define a new / custom text variable that uses the file modification time but with your own explicit format, then insert your custom variable instead of the pre-defined &#8220;Modification Date&#8221; variable.</p>

<p>In my brief testing this custom variable and its format is preserved when pasting the text frame into other documents that were created on other systems.</p>

<p>But now I want to know exactly how the format is chosen for the built-in &#8220;Modification Date&#8221; variable. I am guessing that when a story with a variable is pasted into a document the format is determined by the format of an existing variable of the same name, and if there is no existing variable of that name then InDesign brings in the new variable definition (along with its format) from the clipboard.</p>

<p><a href="http://www.youtube.com/watch?v=ZkuCPYf16xI">But why models?</a></p>

<p>No, that&#8217;s not what I mean&#8230; why the default date format? I tried changing the date formats in System Preferences. Doesn&#8217;t seem that InDesign picks it up from there. I tried trashing the <em>Adobe InDesign</em> preferences folder, changing the date format in System Preferences and launching InDesign again. InDesign is still using the original format, so doesn&#8217;t get it from the user&#8217;s preferences. I had a look through <code>~/Library/Preferences/com.adobe.InDesign.plist</code> but nothing date-related in there.</p>

<p>Perhaps it is set by the local-domain <code>/Library/Preferences/*</code>. Perhaps it is set by the built-in preferences of your installed language version of Creative Suite. Perhaps&#8230;</p>

<p>So I gave up. I will leave the investigation for some day when I am younger and it is more important to understand how Adobe&#8217;s InDesign picks the format for the built-in date modified variable. The workaround works around.</p>

<p>Suite!</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/09/indesign-variable-formatting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free software FTW! Updated filetimes.py</title>
		<link>http://reliablybroken.com/b/2011/09/free-software-ftw-updated-filetimes-py/</link>
		<comments>http://reliablybroken.com/b/2011/09/free-software-ftw-updated-filetimes-py/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 13:36:50 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[active directory]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=674</guid>
		<description><![CDATA[Two years ago (flippin&#8217; heck it seems like only yesterday) I wrote about converting between Unix timestamps and Windows timestamps using Python. In that post I linked to my very simple implementation of a module that provides converting back and forth between the formats. A few weeks ago I received an e-mail from Timothy Williams [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://reliablybroken.com/b/2009/09/working-with-active-directory-filetime-values-in-python/">Two years ago</a> (flippin&#8217; heck it seems like only yesterday) I wrote about converting between Unix timestamps and Windows timestamps using Python. In that post I linked to my very simple implementation of a module that provides converting back and forth between the formats.</p>

<p>A few weeks ago I received an e-mail from Timothy Williams with changes to the my module so that it preserves the fractions of a second in the conversion. How sweet is that?!?!! Exclamation mark question mark exclamation mark cellida diaresis em-dash full stop king of punctuation.</p>

<p>It is fantastic that not only did someone find my code useful but also that they were generous enough to take the time to improve it and give the changes back to me. I love tasty, delicious free software and the people like Tim who make it tastier and more delicious.</p>

<p>So here is the new version of <a href="http://reliablybroken.com/b/wp-content/filetimes.py">filetimes.py incorporating Tim&#8217;s fixes</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/09/free-software-ftw-updated-filetimes-py/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>XPath bug in old versions of ElementTree</title>
		<link>http://reliablybroken.com/b/2011/09/xpath-bug-elementtree/</link>
		<comments>http://reliablybroken.com/b/2011/09/xpath-bug-elementtree/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 10:47:46 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=669</guid>
		<description><![CDATA[I figured out why my XML parsing code works fine using the pure-Python ElementTree XML parsing module but fails when using the speedy and memory-optimized cElementTree XML parsing module. The XPath 1.0 specification says '.' is short-hand for 'self::node()', selecting a node itself. Parsing an XML document and selecting the context node with ElementTree in [...]]]></description>
			<content:encoded><![CDATA[<p>I figured out why my XML parsing code works fine using the <a href="http://effbot.org/zone/element-index.htm">pure-Python ElementTree XML parsing module</a> but fails when using <a href="http://effbot.org/zone/celementtree.htm">the speedy and memory-optimized cElementTree XML parsing module</a>.</p>

<p><a href="http://www.w3.org/TR/xpath/">The XPath 1.0 specification</a> says <code>'.'</code> is short-hand for <code>'self::node()'</code>, selecting a node itself.</p>

<p>Parsing an XML document and selecting the context node with ElementTree in Python 2.5:</p>

<pre><code>&gt;&gt;&gt; from xml.etree import ElementTree
&gt;&gt;&gt; ElementTree.VERSION
'1.2.6'
&gt;&gt;&gt; doc = "&lt;Root&gt;&lt;Example&gt;BUG&lt;/Example&gt;&lt;/Root&gt;"
&gt;&gt;&gt; node1 = ElementTree.fromstring(doc).find('./Example')
&gt;&gt;&gt; node1
&lt;Element Example at 10e0ed8c0&gt;
&gt;&gt;&gt; node1.find('.')
&lt;Element Example at 10e0ed8c0&gt;
&gt;&gt;&gt; node1.find('.') == node1
True
</code></pre>

<p>See how the result of <code>node1.find('.')</code> is the node itself? <a href="http://www.w3.org/TR/xpath/#path-abbrev">As it should be</a>.</p>

<p>Parsing an XML document and selecting the context node with cElementTree in Python 2.5:</p>

<pre><code>&gt;&gt;&gt; from xml.etree import cElementTree
&gt;&gt;&gt; doc = "&lt;Root&gt;&lt;Example&gt;BUG&lt;/Example&gt;&lt;/Root&gt;"
&gt;&gt;&gt; node2 = cElementTree.fromstring(doc).find('./Example')
&gt;&gt;&gt; node2
&lt;Element 'Example' at 0x10e0e3660&gt;
&gt;&gt;&gt; node2.find('.')
&gt;&gt;&gt; node2.find('.') == node2
False
</code></pre>

<p>Balls. The result of <code>node2.find('.')</code> is <code>None</code>.</p>

<p>However! I have a kludgey work-around that works whether you use ElementTree or cElementTree. Use <code>'./'</code> instead of <code>'.'</code>:</p>

<pre><code>&gt;&gt;&gt; node1.find('./')
&lt;Element Example at 10e0ed8c0&gt;
&gt;&gt;&gt; node1.find('./') == node1
True
&gt;&gt;&gt; node2.find('./')
&lt;Element 'Example' at 0x10e0e3660&gt;
&gt;&gt;&gt; node2.find('./') == node2
True
</code></pre>

<p><em>Kludgey because <code>'./'</code> is not a valid XPath expression.</em></p>

<p>So we are back on track. Also works for Python 2.6 which has the same version of ElementTree.</p>

<p>Fortunately Python 2.7 got a new version of ElementTree and the bug is fixed:</p>

<pre><code>&gt;&gt;&gt; from xml.etree import ElementTree
&gt;&gt;&gt; ElementTree.VERSION
'1.3.0'
&gt;&gt;&gt; doc = "&lt;Root&gt;&lt;Example&gt;BUG&lt;/Example&gt;&lt;/Root&gt;"
&gt;&gt;&gt; node3 = ElementTree.fromstring(doc).find('./Example')
&gt;&gt;&gt; node3
&lt;Element 'Example' at 0x107257210&gt;
&gt;&gt;&gt; node3.find('.')
&lt;Element 'Example' at 0x107257210&gt;
&gt;&gt;&gt; node3.find('.') == node3
True
</code></pre>

<p>However! They also fixed my kludgey work-around:</p>

<pre><code>&gt;&gt;&gt; node3.find('./')
&gt;&gt;&gt; node3.find('./') == node3
False
</code></pre>

<p>So I can&#8217;t code something that works for all three versions. This is annoying. I was hoping to just replace ElementTree with the C version, makes my code run in one third the time (the XML parts of it run in one tenth the time). And cannot install any compiled modules &#8211; the code can only rely on Python 2.5&#8242;s standard library.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/09/xpath-bug-elementtree/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lion: Spotlight still broken</title>
		<link>http://reliablybroken.com/b/2011/08/lion-spotlight-still-broken/</link>
		<comments>http://reliablybroken.com/b/2011/08/lion-spotlight-still-broken/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 20:32:40 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[spotlight]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=665</guid>
		<description><![CDATA[I&#8217;ve installed Mac OS X 10.7 (upgrading from 10.6) and was very interested to see how the new search tokens feature would work in Spotlight. But on my Mac it doesn&#8217;t. Here&#8217;s the result of a search for files whose name contains the text &#8220;david buxton&#8221;: Note how none of the files in that list [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve installed <a href="http://www.apple.com/pr/library/2011/06/06Mac-OS-X-Lion-With-250-New-Features-Available-in-July-From-Mac-App-Store.html">Mac OS X 10.7</a> (upgrading from 10.6) and was very interested to see how the new search tokens feature would work in Spotlight. But on my Mac it doesn&#8217;t. Here&#8217;s the result of a search for files whose name contains the text &#8220;david buxton&#8221;:</p>

<p><a href="http://reliablybroken.com/b/wp-content/uploads/2011/08/spotlight-still-shit.jpg"><img src="http://reliablybroken.com/b/wp-content/uploads/2011/08/spotlight-still-shit.jpg" alt="" title="spotlight-still-shit" width="568" height="326" class="aligncenter size-full wp-image-666" /></a></p>

<p>Note how none of the files in that list has a name containing the text &#8220;david buxton&#8221;.</p>

<p>Perhaps deleting the Spotlight index would fix things. Meh.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/08/lion-spotlight-still-broken/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CSV sucks</title>
		<link>http://reliablybroken.com/b/2011/07/csv-sucks/</link>
		<comments>http://reliablybroken.com/b/2011/07/csv-sucks/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 00:37:48 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[excel]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=656</guid>
		<description><![CDATA[For future reference: CSV is a terrible format for spreadsheet data. Any by spreadsheet data I mean CSV is a terrible format for text data that will be opened in Microsoft Excel (unless you only speak English). My objection to CSV as a spreadsheet format is it has no way to indicate the text encoding, [...]]]></description>
			<content:encoded><![CDATA[<p>For future reference: <a href="http://en.wikipedia.org/wiki/Comma-separated_values">CSV</a> is a terrible format for spreadsheet data.</p>

<p>Any by spreadsheet data I mean CSV is a terrible format for text data that will be opened in <a href="http://office.microsoft.com/en-us/excel/">Microsoft Excel</a> (unless you only speak English).</p>

<p>My objection to CSV as a spreadsheet format is it has no way to indicate the text encoding, and Excel (at least Excel 2008 for Mac and Excel 2007 for Windows) has no way of choosing the encoding when opening a CSV file. When your data is text from any number of non-English languages you will likely be dealing with characters outside the standard &#8216;latin-1&#8242; character set.</p>

<p>Even if Excel did have a little pop-up menu for choosing the encoding when opening a CSV file, it would mean instructing your Excel-happy friends to &#8220;open as UTF-8&#8243; whenever they wanted to open your CSV data.</p>

<p>Wot you mean you don&#8217;t have Excel-happy friends?</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/07/csv-sucks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Styling your Excel data with xlwt</title>
		<link>http://reliablybroken.com/b/2011/07/styling-your-excel-data-with-xlwt/</link>
		<comments>http://reliablybroken.com/b/2011/07/styling-your-excel-data-with-xlwt/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 23:34:33 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=648</guid>
		<description><![CDATA[This post is about how to create styles in Excel spreadsheets with the most excellent xlwt for Python. The documentation for xlwt (version 0.7.2) is a little sketchy on how to use formatting. So here goes&#8230; To apply formatting to a cell you pass an instance of the xlwt.XFStyle class as the fourth argument to [...]]]></description>
			<content:encoded><![CDATA[<p>This post is about how to create styles in <a href="http://office.microsoft.com/en-us/excel/">Excel spreadsheets</a> with <a href="http://www.python-excel.org/">the most excellent xlwt</a> for <a href="http://www.python.org/">Python</a>. The documentation for xlwt (version 0.7.2) is a little sketchy on how to use formatting. So here goes&#8230;</p>

<p>To apply formatting to a cell you pass an instance of the <code>xlwt.XFStyle</code> class as the fourth argument to the <code>xlwt.Worksheet.write</code> method. The best way to create an instance is to use the <code>xlwt.easyxf</code> helper, which takes a string that specifies the formatting for a cell.</p>

<p>The other thing about using styles is you should only make one instance of each, then pass that same style object every time you want to apply it to a cell.</p>

<p>An example which uses a few styles:</p>

<pre><code>import xlwt

styles = dict(
    bold = 'font: bold 1',
    italic = 'font: italic 1',
    # Wrap text in the cell
    wrap_bold = 'font: bold 1; align: wrap 1;',
    # White text on a blue background
    reversed = 'pattern: pattern solid, fore_color blue; font: color white;',
    # Light orange checkered background
    light_orange_bg = 'pattern: pattern fine_dots, fore_color white, back_color orange;',
    # Heavy borders
    bordered = 'border: top thick, right thick, bottom thick, left thick;',
    # 16 pt red text
    big_red = 'font: height 320, color red;',
)
</code></pre>

<p>I have no idea what it is based on, but 20 = 1 pt. So 320 = 16 pt text.</p>

<pre><code>book = xlwt.Workbook()
sheet = book.add_sheet('Style demo')

for idx, k in enumerate(sorted(styles)):
    style = xlwt.easyxf(styles[k])
    sheet.write(idx, 0, k)
    sheet.write(idx, 1, styles[k], style)

book.save('Example.xls')
</code></pre>

<p>It isn&#8217;t included with <a href="http://pypi.python.org/pypi/xlwt/0.7.2">the current distribution on the cheese shop</a>, but there is <a href="https://secure.simplistix.co.uk/svn/xlwt/tags/0.7.2/xlwt/doc/pattern_examples.xls">a useful Excel spreadsheet demonstrating cell patterns</a> in the source repository.</p>

<p>You can find the complete list of possible cell formats by reading <a href="https://secure.simplistix.co.uk/svn/xlwt/tags/0.7.2/xlwt/Style.py">the source for <code>xlwt.Styles</code></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/07/styling-your-excel-data-with-xlwt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VCS for Cocoa Programming for Mac OS X</title>
		<link>http://reliablybroken.com/b/2011/04/next-edition-of-cocoa-programming/</link>
		<comments>http://reliablybroken.com/b/2011/04/next-edition-of-cocoa-programming/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 21:35:36 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=638</guid>
		<description><![CDATA[I am working my way through Aaron Hillegass&#8216; Cocoa Programming for Mac OS X (again). I find it a good book, despite the fact I&#8217;ve started it twice before and have abandoned my tuition twice before. I like to think my progression is an awful lot like young Luke Skywalker recklessly abandoning his Jedi training [...]]]></description>
			<content:encoded><![CDATA[<p>I am working my way through <a href="http://www.bignerdranch.com/instructors/hillegass.shtml">Aaron Hillegass</a>&#8216; <a href="http://www.bignerdranch.com/book/cocoa%C2%AE_programming_for_mac%C2%AE_os_x_3rd_edition">Cocoa Programming for Mac OS X</a> (again). I find it a good book, despite the fact I&#8217;ve started it twice before and have abandoned my tuition twice before. I like to think my progression is an awful lot like young <a href="http://www.youtube.com/watch?v=om6ctZWNw18">Luke Skywalker recklessly abandoning his Jedi training</a> on Dagobah in order to save his Web application friends in the cloud city called Bespinternet. Eventually Luke (and I) will go back to complete his (and my) training and will become a truly great Jedi programmer for Mac OS X.</p>

<p>Anyway, for the first few chapters the book leads you through a number of small applications, each exercise starting a new project. Then in the later chapters Hillegass has you adding features to a single project called RaiseMan.</p>

<p>It strikes me that the next edition of the book should introduce using version control to track development.</p>

<p>Many chapters in the book end with challenges that go off on a tangent, getting you to implement alternate approaches to the exercises covered in that chapter. But then the subsequent chapter will expect you to work with the version of the RaiseMan application as it stood before the previous chapter&#8217;s programming challenge.</p>

<p>This is a natural fit for revision control (aka <a href="http://en.wikipedia.org/wiki/Revision_control">VCS</a>). The book would teach you how to tag &#8220;release&#8221; versions of your code. It would teach you how to create an experimental feature branch for the chapter-end challenges, and then how to resume development from the last &#8220;release&#8221; version for the next chapter&#8217;s main exercises.</p>

<p>This is particularly relevant now that <a href="https://github.com/blog/810-xcode-4-released-with-git-integration">Xcode 4 includes Git integration</a>. Of course there is no reason one can&#8217;t employ a suitable version control system with the current (third) edition of the book; I just think it makes a lot of sense to get younglings used to this workflow while teaching them all the other stuff about lightsabres and <a href="http://www.folklore.org/StoryView.py?project=Macintosh&amp;story=Reality_Distortion_Field.txt">the Force</a> while you&#8217;re at it.</p>

<p>You will up-vote this on <a href="http://reddit.com/">Reddit</a> / <a href="http://news.ycombinator.com/">Hacker News</a> <em>(waves hand like her Imperial majesty)</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/04/next-edition-of-cocoa-programming/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adobe Software Updates</title>
		<link>http://reliablybroken.com/b/2011/03/adobe-software-updates/</link>
		<comments>http://reliablybroken.com/b/2011/03/adobe-software-updates/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 01:03:36 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[adobe]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=620</guid>
		<description><![CDATA[What Adobe&#8217;s software update site needs is: An RSS / Atom feed of recent updates. This way you can subscribe to a list of recent updates in your favourite news reader and be informed when a new update is released without having to scan product-specific blogs, etc. Per-product pages listing available updates. When you want [...]]]></description>
			<content:encoded><![CDATA[<p>What Adobe&#8217;s software update site needs is:</p>

<ul>
<li><p><a href="http://reliablybroken.com/wavesinspace/adobe/feed/">An RSS / Atom feed of recent updates</a>.</p>

<p>This way you can subscribe to a list of recent updates in your favourite news reader and be informed when a new update is released without having to scan product-specific blogs, etc.</p></li>
<li><p><a href="http://reliablybroken.com/wavesinspace/adobe/">Per-product pages listing available updates</a>.</p>

<p>When you want to find an update for a product you can find it on the dedicated product update page. It will be there.</p></li>
<li><p><a href="http://reliablybroken.com/wavesinspace/adobe/acrobat/">Nice URLs</a>.</p>

<p>URLs make the Web. Putting the product name in the URL makes a human-friendly URL, as opposed to putting the opaque product reference numeric key as a query parameter. Quick test: which updates do you expect to see on <a href="http://www.adobe.com/support/downloads/product.jsp?product=1&amp;platform=Macintosh">http://www.adobe.com/support/downloads/product.jsp?product=1&amp;platform=Macintosh</a> ? And assuming you were so insane as to guess the previous URL correctly, which updates do you expect to see on <a href="http://www.adobe.com/support/downloads/product.jsp?product=1">http://www.adobe.com/support/downloads/product.jsp?product=1</a></p></li>
</ul>

<p>Anyway, those be my principal beefs with the current Adobe software updates site. So I made a site that tries to satisfy my beeves. Beefs.</p>

<p>It is here: <a href="http://reliablybroken.com/wavesinspace/">http://reliablybroken.com/wavesinspace/</a></p>

<p>Please provide feedback to <a href="mailto:david@gasmark6.com">david@gasmark6.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/03/adobe-software-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe&#8217;s software update site is shit</title>
		<link>http://reliablybroken.com/b/2011/03/adobes-update-site/</link>
		<comments>http://reliablybroken.com/b/2011/03/adobes-update-site/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 00:08:48 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[adobe]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=615</guid>
		<description><![CDATA[This is written from the point of view of someone looking to keep abreast of software patches for Adobe&#8216;s many excellent products (also Acrobat). Adobe&#8217;s Downloads page is mostly about downloading product demos. Although on that page there is a list on the side with a link to the real product updates page and a [...]]]></description>
			<content:encoded><![CDATA[<p>This is written from the point of view of someone looking to keep abreast of software patches for <a href="http://www.adobe.com/">Adobe</a>&#8216;s many excellent products (also Acrobat).</p>

<p>Adobe&#8217;s <a href="http://www.adobe.com/downloads/">Downloads page</a> is mostly about downloading product demos. Although on that page there is a list on the side with a link to the real product updates page and a very out-dated list of updates.</p>

<p>So then the actual <a href="http://www.adobe.com/downloads/updates/">Product Updates page</a> has a menu for all their products that takes you to the updates for an individual product, and a list of &#8220;featured updates&#8221;. What qualifies an update to be featured is a mystery, so that list is not useful either.</p>

<p>They don&#8217;t think to mention it on the Downloads or Product Updates pages, but there is also a <a href="http://www.adobe.com/support/downloads/new.jsp">New Downloads page</a> which is actually rather handy, although there is no indication what constitutes &#8220;new&#8221; so it can be difficult to tell if something was released in the time between your last visit and the oldest update mentioned on that page.</p>

<p>My favourite aspect of Adobe&#8217;s support pages is the whimsical approach to the page for a product. For example, <a href="http://www.adobe.com/support/downloads/product.jsp?product=27&amp;platform=Macintosh">the page for Illustrator for Macintosh</a> includes the 15.0.2 update for Illustrator that shipped as part of Creative Suite version 5. Meanwhile <a href="http://www.adobe.com/support/downloads/collection.jsp?collID=1&amp;platform=Macintosh">the Creative Suite for Mac updates page</a> doesn&#8217;t admit there have been any updates for CS5 at all.</p>

<p>What Adobe&#8217;s software update site needs is&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/03/adobes-update-site/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building Nginx 0.9.5 on Debian Lenny</title>
		<link>http://reliablybroken.com/b/2011/03/building-nginx-on-debian-lenny/</link>
		<comments>http://reliablybroken.com/b/2011/03/building-nginx-on-debian-lenny/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 21:00:33 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=609</guid>
		<description><![CDATA[Nginx is available in Debian Lenny, but the version in stable is the old 0.6.x series. Perusio maintains a useful repository with development versions built for Lenny, but it requires libraries newer than those in stable. UPDATED: fixed &#8216;build-essential&#8217; &#8211; thank you Carlos But it is easy enough to build a deb from the Perusio [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nginx.org/">Nginx</a> is available in <a href="http://www.debian.org/releases/lenny/">Debian Lenny</a>, but the version in stable is the old 0.6.x series. <a href="http://debian.perusio.net/">Perusio maintains a useful repository</a> with development versions built for Lenny, but it requires libraries newer than those in stable.</p>

<p><em>UPDATED: fixed &#8216;build-essential&#8217; &#8211; thank you Carlos</em></p>

<p>But it is easy enough to build a <a href="http://www.debian.org/doc/FAQ/ch-pkg_basics">deb</a> from the Perusio package which uses the stable libraries. Here are my notes. N.B. Editing the apt sources and installing packages needs root privileges.</p>

<p>First, add the Perusio repository to <code>/etc/apt/sources.list</code>:</p>

<pre><code>cat &gt;&gt; /etc/apt/sources.list &lt;&lt;EOF
deb http://debian.perusio.net unstable/
deb-src http://debian.perusio.net unstable/
EOF
</code></pre>

<p>Update the apt-get index:</p>

<pre><code>apt-get update
</code></pre>

<p>Install packaging tools (if they aren&#8217;t installed already):</p>

<pre><code>apt-get install dpkg-dev
apt-get install fakeroot
apt-get install debhelper
apt-get install build-essential
</code></pre>

<p>Install headers for libaries required to build Nginx:</p>

<pre><code>apt-get install autotools-dev libgeoip-dev libssl-dev libpcre3-dev zlib1g-dev
</code></pre>

<p>Now get the package source and build a deb installation package. This part can be done as a non-root user.</p>

<pre><code>apt-get source nginx
cd nginx-0.9.5
dpkg-buildpackage -rfakeroot -uc -b
</code></pre>

<p>When I did this, the version in the repository was Nginx 0.9.5. The flag <code>-uc</code> says to not sign the changes file and <code>-b</code> says build a binary-only distribution. If you were cross-compiling, you can pass the <code>-a</code> flag to dpkg-buildpackage specifying the build architecture.</p>

<p>Assuming the build was successful, your new installation package will have been created in the parent directory (bloody hell Debian tools are unintuitive).</p>

<p>Here I built the deb on amd64. To install this I go:</p>

<pre><code>dpkg -i ../nginx_0.9.5-perusio.1.0_amd64.deb
</code></pre>

<p>The advantage of building Nginx from Perusio&#8217;s repository rather than directly from the source is we get the hard work of conforming to the Debian layout for free.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/03/building-nginx-on-debian-lenny/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Caching a Django app with Nginx + FastCGI</title>
		<link>http://reliablybroken.com/b/2011/02/caching-django-nginx/</link>
		<comments>http://reliablybroken.com/b/2011/02/caching-django-nginx/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 19:58:32 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=605</guid>
		<description><![CDATA[I just spent a stupid amount of time trying to figure why Nginx was failing to cache my Django app responses. The Django app is running as a FastCGI backend and I have Nginx using the fastcgi_cache directive to cache responses. The answer is that Nginx since version 0.8.44 does not cache backend responses if [...]]]></description>
			<content:encoded><![CDATA[<p>I just spent a stupid amount of time trying to figure why <a href="http://nginx.org/">Nginx</a> was failing to cache my <a href="http://www.djangoproject.com/">Django</a> app responses. The Django app is running as a FastCGI backend and I have Nginx using the <a href="http://wiki.nginx.org/HttpFcgiModule#fastcgi_cache"><code>fastcgi_cache</code> directive</a> to cache responses.</p>

<p>The answer is that <a href="http://nginx.org/en/CHANGES">Nginx since version 0.8.44 does not cache backend responses if they have a &#8220;Set-Cookie&#8221; header</a>. This makes perfect sense because you don&#8217;t want a response which sets a cookie to be cached for subsequent requests, but I was stupid because I had totally forgotten that my Django app was using a POST form for all responses for non-authenticated clients (due to how <a href="http://docs.djangoproject.com/en/dev/ref/contrib/csrf/">Django&#8217;s CSRF middleware</a> does its stuff).</p>

<p>The solution was to change the app so that it uses the GET method on the form in question, which in this case is fine from a security point-of-view.</p>

<p>The moral of this story is I should pay attention to my HTTP response headers and that I am badly short-sighted both figuratively and literally. With that fixed the site has gone from 15 requests per second to ~2000 requests per second!</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/02/caching-django-nginx/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Microsoft isn&#8217;t totally evil</title>
		<link>http://reliablybroken.com/b/2011/02/microsoft-isnt-totally-evil/</link>
		<comments>http://reliablybroken.com/b/2011/02/microsoft-isnt-totally-evil/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 23:18:38 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=599</guid>
		<description><![CDATA[Pierre Igot complains about the font rendering on Microsoft&#8217;s Office for Mac product pages: Why does the web site promoting Microsoft Office for Mac OS X use, by default, a font that no Mac OS X user has on his or her system? Well, the branding for Mac Office uses Segoe so it makes sense [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.betalogue.com">Pierre Igot</a> complains about the font rendering on <a href="http://www.microsoft.com/mac/">Microsoft&#8217;s Office for Mac</a> product pages:</p>

<blockquote>
  <p><a href="http://www.betalogue.com/2011/02/10/microsoft-segoe/">Why does the web site promoting Microsoft Office for Mac OS X use, by default, a font that no Mac OS X user has on his or her system?</a></p>
</blockquote>

<p>Well, the branding for Mac Office uses Segoe so it makes sense to keep that brand consistent across all the pages. But it was more of a rhetorical question, wasn&#8217;t it?</p>

<p>But Pierre has missed that the text is not displayed using a font specified by the stylesheet (he notes that he doesn&#8217;t have Segoe installed). What actually happens is it is rendered as canvas elements, one for each word.</p>

<p>This works using a JavaScript library called <a href="http://cufon.shoqolate.com/generate/">Cufón</a> which aims to allow text to be rendered using any font the designer specifies, even if the font is not installed on the visitor&#8217;s computer. In the good old days the text would have been rendered as a graphic (as the designer did for the &#8216;Office:mac&#8217; logo at the top of the page) but modern Web designers are too cool for that.</p>

<p>The advantage of the crazy download-able fonts and client-side JavaScript approach is the headline text remains accessible, you can copy and paste it etc. And at larger sizes it looks pretty good; only the smaller headline text renders poorly.</p>

<p>This screenshot shows how well it works for large size text and poorly for the small text (taken in Google Chrome dev version). I&#8217;ve selected part of the text to demonstrate that it is &#8220;live&#8221;:</p>

<p><a href="http://reliablybroken.com/b/wp-content/uploads/2011/02/ms-segoe-cufon.jpg"><img src="http://reliablybroken.com/b/wp-content/uploads/2011/02/ms-segoe-cufon.jpg" alt="Screenshot of Microsoft&#039;s Mac site" title="ms-segoe-cufon" width="600" height="160" class="aligncenter size-full wp-image-602" /></a></p>

<p>Pierre is right, the smaller headline text does look terrible for the very same visitors Microsoft wants to sell to. But I don&#8217;t mind too much because the whole site is much less of a useability nightmare since the re-design. Microsoft&#8217;s Mac Web designers aren&#8217;t entirely evil.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/02/microsoft-isnt-totally-evil/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Weird App Store buttons</title>
		<link>http://reliablybroken.com/b/2011/01/weird-app-store-buttons/</link>
		<comments>http://reliablybroken.com/b/2011/01/weird-app-store-buttons/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 19:26:06 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[hig]]></category>
		<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=592</guid>
		<description><![CDATA[Screenshot of App Store.app showing title bar buttons out of place. Why did Apple allow the new App Store application to ignore the human interface guidelines? It isn&#8217;t like the toolbar is doing anything radically different to other information browsers, nothing that might warrant exploring new interface ideas. It just looks odd, an arbitrary inconsistency [...]]]></description>
			<content:encoded><![CDATA[<p>Screenshot of <code>App Store.app</code> showing title bar buttons out of place.</p>

<p><a href="http://reliablybroken.com/b/wp-content/uploads/2011/01/appstore-buttons.jpg"><img src="http://reliablybroken.com/b/wp-content/uploads/2011/01/appstore-buttons.jpg" alt="" title="appstore-buttons" width="417" height="100" class="aligncenter size-full wp-image-593" /></a></p>

<p>Why did Apple allow <a href="http://www.apple.com/mac/app-store/">the new App Store application</a> to ignore the <a href="http://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGWindows/XHIGWindows.html#//apple_ref/doc/uid/20000961-TPXREF51">human interface guidelines</a>? It isn&#8217;t like the toolbar is doing anything radically different to other information browsers, nothing that might warrant exploring new interface ideas.</p>

<p>It just looks odd, an arbitrary inconsistency that would be simple to correct.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2011/01/weird-app-store-buttons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running minidlna on Mac</title>
		<link>http://reliablybroken.com/b/2010/12/running-minidlna-on-mac/</link>
		<comments>http://reliablybroken.com/b/2010/12/running-minidlna-on-mac/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 11:49:05 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[dlna]]></category>
		<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=586</guid>
		<description><![CDATA[These are my notes on installing minidlna, a DLNA server for Mac OS X. I compiled it from source and installed the supporting libraries from MacPorts. Most of this was culled from a thread on the minidlna forum. First install each of the following ports. The command for each would be something like sudo port [...]]]></description>
			<content:encoded><![CDATA[<p>These are my notes on installing <a href="http://sourceforge.net/projects/minidlna/">minidlna</a>, a <a href="http://www.dlna.org/">DLNA</a> server for Mac OS X. I compiled it from source and installed the supporting libraries from <a href="http://www.macports.org/">MacPorts</a>.</p>

<p>Most of this was culled from <a href="http://sourceforge.net/projects/minidlna/forums/forum/879956/topic/3412747">a thread on the minidlna forum</a>.</p>

<p>First install each of the following ports. The command for each would be something like <code>sudo port install libiconv</code>.</p>

<ul>
<li>libiconv</li>
<li>sqlite3</li>
<li>jpeg</li>
<li>libexif</li>
<li>libid3tag</li>
<li>libogg</li>
<li>libvorbis</li>
<li>flac</li>
<li>ffmpeg</li>
</ul>

<p>Then check out the Mac branch of the current minidlna source from the CVS repository.</p>

<pre><code>cvs -d:pserver:anonymous@minidlna.cvs.sourceforge.net:/cvsroot/minidlna checkout -r osx_port minidlna
cd minidlna
</code></pre>

<p>The current build script appears to miss out pulling in libiconv so I had to edit <code>configure.ac</code>, inserting a line to bring in <code>libiconv</code>.</p>

<pre><code>AC_CHECK_LIB([iconv], [main],, AC_MSG_ERROR(Cannot find required library iconv.))
</code></pre>

<p>Now the build will work. Although I found I needed to run <code>autogen.sh</code> twice for it to generate all the necessary files.</p>

<pre><code>source ENVIRONMENT.macports
sh genconfig.sh
sh autogen.sh
sh autogen.sh
./configure
make
</code></pre>

<p>This spits out the minidlna executable and a basic configuration file. Copy these to wherever you want them. Edit the <code>minidlna.conf</code> file, pointing it at the files you want to serve. There are examples of what to do in that configuration file.</p>

<p>And for testing purposes you can start the server from the build directory.</p>

<pre><code>./minidlna -d -f minidlna.conf
</code></pre>

<p>Bingo.</p>

<p>I did try using <a href="http://ushare.geexbox.org/">ushare</a>, another DLNA server, but I couldn&#8217;t figure out how to persuade my Sony telly to successfully connect to it. So I gave up. I feel it is useful to give up quickly when something doesn&#8217;t work until you run out of alternatives, I consider this triage. I also consider my telly&#8217;s inability to work with ushare and the fact that the telly will only play a very limited set of video formats a mark against the promise of DLNA.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2010/12/running-minidlna-on-mac/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Class-based views for Bottle</title>
		<link>http://reliablybroken.com/b/2010/12/class-based-views-for-bottle/</link>
		<comments>http://reliablybroken.com/b/2010/12/class-based-views-for-bottle/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 21:39:46 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[bottle]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=578</guid>
		<description><![CDATA[I&#8217;m not convinced this is actually a good idea, but I have an approach for using class-based views as handlers for a route with Bottle. (If you were mad keen on Django&#8217;s shift to class-based views you might reckon life wouldn&#8217;t be complete with a Bottle-based application until you employ classes for views. However Bottle&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not convinced this is actually a good idea, but I have an approach for using class-based views as handlers for a route with <a href="http://bottle.paws.de/">Bottle</a>.</p>

<p><em>(If you were mad keen on <a href="http://www.djangoproject.com/">Django&#8217;s</a> shift to <a href="http://docs.djangoproject.com/en/dev/topics/class-based-views/">class-based views</a> you might reckon life wouldn&#8217;t be complete with a Bottle-based application until you employ classes for views. However Bottle&#8217;s use of decorators for tying URLs to views means it is less a natural fit than the same thing in Django.)</em></p>

<p>The problem is that you can&#8217;t just decorate the method in your class using <a href="http://bottle.paws.de/docs/dev/api.html#routing"><code>bottle.route</code></a> because if you use that decorator on a method in a class you are telling Bottle to use the method before it has been bound to an instance of that class.</p>

<p>So although I wish it did, the following example will not work:</p>

<pre><code>import bottle

class ViewClass(object):
    @bottle.route("/")
    def home_view(self):
        return "My home page."

obj = ViewClass()
bottle.run()
</code></pre>

<p>Running that will lead to errors about not enough arguments passed to the view method of your <code>ViewClass</code> instance.</p>

<p>Instead you need to register the route right after the object is created. This can be done in <a href="http://docs.python.org/reference/datamodel.html#object.__new__">the class&#8217;s <code>__new__</code> method</a>:</p>

<pre><code>import bottle

class ViewClass(object):
    def __new__(cls, *args, **kwargs):
        obj = super(ViewClass, cls).__new__(cls, *args, **kwargs)
        bottle.route("/")(obj.home_view)
        return obj

    def home_view(self):
        return "My home page."

obj = ViewClass()
bottle.run()
</code></pre>

<p>It works. It isn&#8217;t that pretty. You could achieve exactly the same thing by explicitly passing the <code>obj.home_view</code> method to <code>bottle.route</code> <em>after</em> the instance is created. The advantage to doing this in the <code>__new__</code> method is it will happen automatically whenever <code>ViewClass</code> is instantiated.</p>

<p>And if you go down this path then <a href="http://bottle.paws.de/docs/dev/tutorial.html#accessing-request-data">you should be aware of threads</a>. Hey! Nice threads! Also I have a cold.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2010/12/class-based-views-for-bottle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac deployment Wiki</title>
		<link>http://reliablybroken.com/b/2010/10/mac-deployment-wiki/</link>
		<comments>http://reliablybroken.com/b/2010/10/mac-deployment-wiki/#comments</comments>
		<pubDate>Sat, 16 Oct 2010 15:08:40 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=573</guid>
		<description><![CDATA[The OS X Deployment and Management Wiki, articles about managing and deploying Macintoshes. Looks like it is the work of Rusty Myers and Nate Walck (so far).]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.osxdeployment.info/">OS X Deployment and Management Wiki</a>, articles about managing and deploying Macintoshes.</p>

<p>Looks like it is the work of <a href="http://twitter.com/thespider">Rusty Myers</a> and Nate Walck (so far).</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2010/10/mac-deployment-wiki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Startup times for old Macs</title>
		<link>http://reliablybroken.com/b/2010/10/startup-times-for-old-macs/</link>
		<comments>http://reliablybroken.com/b/2010/10/startup-times-for-old-macs/#comments</comments>
		<pubDate>Sat, 02 Oct 2010 21:21:37 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=561</guid>
		<description><![CDATA[Considering it is only a PowerPC G4 processor running at 1.5 GHz, I am impressed that my five-year-old little MacMini can go from pressing the on button to the login screen in 45 seconds, of which the first 10 seconds is the system trying to work out from which disk it should boot. (There is [...]]]></description>
			<content:encoded><![CDATA[<p>Considering it is only a <a href="http://www.everymac.com/systems/apple/mac_mini/stats/mac_mini_g4_1.5.html">PowerPC G4 processor running at 1.5 GHz</a>, I am impressed that my five-year-old little MacMini can go from pressing the on button to the login screen in 45 seconds, of which the first 10 seconds is the system trying to work out from which disk it should boot. (There is only one disk in the mini &#8211; you hear me mini? Boot from that one immediately.)</p>

<p>However it is another 15 seconds from login to a usable desktop, running Mac OS X 10.5.8. My <a href="http://apple-history.com/?model=classic">Macintosh Classic</a> with an 8 MHz 68000 processor is slightly faster booting <a href="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Macintosh/System/Older_System/System_6.0.x/">System 6.0.8</a>. Both the mini and the classic can run <a href="http://lowendmac.com/compact/68ksoftware.shtml">some version of Eudora</a> for e-mail. Neither machine will run Google&#8217;s Chrome browser so I reckon it is even splits on which is the more useful.</p>

<p>Also I don&#8217;t need an adaptor to plug in the world&#8217;s greatest <a href="http://en.wikipedia.org/wiki/Apple_Extended_Keyboard">aircraft carrier masquerading as a keyboard</a> on the classic. Little baby Jesus to think that Apple used to sell their considerably expensive computers with no keyboard, no screen, no graphics card, no memory, no hard disk, just a mouse! Progress means you can buy a new <a href="http://www.apple.com/macmini/">MacMini</a> and it don&#8217;t come with a mouse neither.</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2010/10/startup-times-for-old-macs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

