<?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>lankycoder</title>
	<atom:link href="http://www.lorrin.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lorrin.org/blog</link>
	<description>Assorted Adventures in Software Development</description>
	<lastBuildDate>Sat, 19 May 2012 16:34:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>VNC to OS X Lion: Gratuitous Passwords and Empty Grey Linen Desktops</title>
		<link>http://www.lorrin.org/blog/2012/03/28/vnc-to-os-x-lion-gratuitous-passwords-and-empty-grey-linen-desktops/</link>
		<comments>http://www.lorrin.org/blog/2012/03/28/vnc-to-os-x-lion-gratuitous-passwords-and-empty-grey-linen-desktops/#comments</comments>
		<pubDate>Thu, 29 Mar 2012 06:36:51 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[VNC]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=172</guid>
		<description><![CDATA[There are two tricks to using VNC from a non Mac to connect to a Mac running OS X Lion. Turn on the VNC server by enabling System Preferences -&#62; Sharing -&#62;  Screen Sharing. Even though it provides little security, a VNC password must be set so that OS X will present an authentication scheme <a href='http://www.lorrin.org/blog/2012/03/28/vnc-to-os-x-lion-gratuitous-passwords-and-empty-grey-linen-desktops/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>There are two tricks to using VNC from a non Mac to connect to a Mac running OS X Lion.</p>
<ol>
<li>Turn on the VNC server by enabling <tt>System Preferences</tt> -&gt; <tt>Sharing</tt> -&gt;  <tt>Screen Sharing</tt>. Even though it provides little security, a VNC password must be set so that OS X will present an authentication scheme that makes sense to a standard VNC client. Enable <tt>VNC viewers may control screen with password</tt><br />
<img class="alignnone  wp-image-175" title="OS X Lion Screen Sharing" src="http://www.lorrin.org/wp-uploads/2012/03/Screen-Shot-2012-03-28-at-10.57.51-PM.png" alt="" width="782" height="662" /></li>
<li>After connecting, you will see a grey linen-backgrounded desktop with nothing in it. Type your user name and password. After logging in, your desktop contents will display!<img class="alignnone  wp-image-179" title="Screenshot at 2012-03-28 23:13:35" src="http://www.lorrin.org/wp-uploads/2012/03/Screenshot-at-2012-03-28-2313351.png" alt="" width="1009" height="648" /></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/03/28/vnc-to-os-x-lion-gratuitous-passwords-and-empty-grey-linen-desktops/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;ERROR:  cannot execute UPDATE in a read-only transaction&#8221;</title>
		<link>http://www.lorrin.org/blog/2012/03/12/error-cannot-execute-update-in-a-read-only-transaction/</link>
		<comments>http://www.lorrin.org/blog/2012/03/12/error-cannot-execute-update-in-a-read-only-transaction/#comments</comments>
		<pubDate>Mon, 12 Mar 2012 20:56:02 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Persistence]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=136</guid>
		<description><![CDATA["ERROR: cannot execute UPDATE in a read-only transaction" is what PostgreSQL tells you when you try to execute an update on a replica instead of on the master.]]></description>
			<content:encoded><![CDATA[<p><code>"ERROR: cannot execute UPDATE in a read-only transaction"</code> is what PostgreSQL tells you when you try to execute an update on a replica instead of on the master.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/03/12/error-cannot-execute-update-in-a-read-only-transaction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Browsing Without Being Tracked</title>
		<link>http://www.lorrin.org/blog/2012/03/10/browsing-without-being-tracked/</link>
		<comments>http://www.lorrin.org/blog/2012/03/10/browsing-without-being-tracked/#comments</comments>
		<pubDate>Sat, 10 Mar 2012 19:03:13 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Privacy]]></category>
		<category><![CDATA[Adblock Plus]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[Do Not Track Plus]]></category>
		<category><![CDATA[Duck Duck Go]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[lso]]></category>
		<category><![CDATA[privacy]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=119</guid>
		<description><![CDATA[TL;DR: Install Do Not Track Plus, use Duck Duck Go (with !sp sometimes) for web searches., To go the extra mile also install Straight Google (requires Greasemonkey), Cookie Whitelist and BetterPrivacy. I don&#8217;t like the idea of advertisers, search engines, and social networks building extensive profiles about what I do online (why). A short-list of <a href='http://www.lorrin.org/blog/2012/03/10/browsing-without-being-tracked/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><a title="Too long; didn't read" href="https://en.wikipedia.org/wiki/TL%3BDR">TL;DR</a>: Install <a href="http://www.abine.com/dntdetail.php">Do Not Track Plus</a>, use <a href="https://duckduckgo.com">Duck Duck Go</a> (with <code>!sp</code> sometimes) for web searches., To go the extra mile also install <a title="Straight Google" href="https://userscripts.org/scripts/show/121261">Straight Google</a> (requires <a href="http://www.greasespot.net/">Greasemonkey</a>), <a href="https://addons.mozilla.org/en-US/firefox/addon/cookie-whitelist-with-buttons/">Cookie Whitelist</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/betterprivacy/">BetterPrivacy</a>.</p>
<p>I don&#8217;t like the idea of advertisers, search engines, and social networks building extensive profiles about what I do online (<a title="Don't Track Us by Duck Duck Go" href="http://donttrack.us/">why</a>). A short-list of tools to avoid such tracking:</p>
<h3>Prevent Inter-Website Tracking</h3>
<ul>
<li>Abine&#8217;s <a href="http://www.abine.com/dntdetail.php">Do Not Track Plus</a> is nearly a one-stop shop. I wish more details were available about what it does, but the gist is:</li>
<ul>
<li>Install and maintain a large number of generic do-not-track-me cookies for many ad networks and tracking services. When content is fetched from these sites, the generic cookie is sent rather than one which is unique to you</li>
<li>Special handling for social buttons (e.g. Like this on Facebook), in which the button fetched anonymously, but, should you choose to click it, the veil is lifted and the Like associated with your account</li>
<li>Many ads are blocked from rendering too, which I hadn&#8217;t expected. Those that remain are innocuous enough that I do not use <a href="https://adblockplus.org/">Ad Block Plus</a> any more.</li>
</ul>
</ul>
<h3>Reduce Google Information Gathering</h3>
<p>I store some personal information on Google (thanks to Google+, Google Calendar, etc.). I do not want to Google to associate that personal information with all the web searches I do every day. Do Not Track Plus is of limited value here: if you sign in to Google, Do Not Track Plus will be obliged to permit your identity to be sent. Additional steps are needed:</p>
<ul>
<li>Don&#8217;t search with Google. I prefer <a href="https://duckduckgo.com">Duck Duck Go</a> for most searches, thanks to their <a href="https://duckduckgo.com/goodies.html">Zero-click Info and other goodies</a>.</li>
<li>For needle-in-the-haystack searches, I find Google often has the best results. <a href="https://startpage.com/eng/">Startpage</a> is an anonymous Google Search proxy. Rather than use it directly, I just prefix my Duck Duck Go searches with <code>!sp</code> when needed.</li>
<li><a title="Straight Google" href="https://userscripts.org/scripts/show/121261">Straight Google</a> (requires <a href="http://www.greasespot.net/">Greasemonkey</a>) prevents <a title="Google’s Click Tracking and How to Disable It" href="http://www.lorrin.org/blog/2012/03/10/googles-click-tracking-and-how-to-disable-it/">Google&#8217;s click-tracking</a>. This is less important if you follow the above steps to avoid doing your web searches at google.com. However, they still track links clicked on their other products, which Straight Google can prevent.</li>
</ul>
<h3>Control Intra-Website Tracking</h3>
<p>The above steps should take care of attempts to track your movement across the web. However, most websites will still store long-term cookies in your browser to track your history of interaction with that particular website.</p>
<ul>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/cookie-whitelist-with-buttons/">Cookie Whitelist</a> is designed to only allow white-listed cookies from being accepted. In practice, this breaks too many websites. For less hassle, configure as follows:</li>
<ul>
<li>Cookie button (the red one): ON. This lets any website set a cookie, but it will be deleted at the end of the session</li>
<li>For the few websites you wish to remain logged in to (or otherwise personalized) click the green button to whitelist as needed</li>
<li>Do not accept third-party cookies</li>
</ul>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/betterprivacy/">BetterPrivacy</a> is to Flash LSOs (local shared objects, or Flash cookies) what Cookie Whitelist is to regular cookies. Alas with a more confusing set of configuration options.</li>
</ul>
<p>Note: this post is (obviously?) not about how to avoid your employer/ISP/government monitoring what you do online. To hide what you are doing from someone who has access to all your traffic, you need encryption and proxying. A good first stop to get some encryption is EFF&#8217;s <a href="https://www.eff.org/https-everywhere">HTTPS Everywhere</a>. This goes a long way to prevent the person nearby in the coffee shop from stealing your Facebook account.</p>
<p>Originally published 2012-03-10. Updated 2012-03-14 with intra-website tracking steps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/03/10/browsing-without-being-tracked/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google&#8217;s Click Tracking and How to Disable It</title>
		<link>http://www.lorrin.org/blog/2012/03/10/googles-click-tracking-and-how-to-disable-it/</link>
		<comments>http://www.lorrin.org/blog/2012/03/10/googles-click-tracking-and-how-to-disable-it/#comments</comments>
		<pubDate>Sat, 10 Mar 2012 18:05:07 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Privacy]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[privacy]]></category>
		<category><![CDATA[tracking]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=120</guid>
		<description><![CDATA[By default, Google tracks every search result you click on. They do this surreptitiously: URLs in Google search results appear to go directly to the destination: &#160; But, upon click, URLs in Google search results change to go to Google first! &#160; Straight Google removes this tracking from Google URLs across all Google products. Easy <a href='http://www.lorrin.org/blog/2012/03/10/googles-click-tracking-and-how-to-disable-it/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>By default, Google tracks every search result you click on. They do this surreptitiously: URLs in Google search results <em>appear</em> to go directly to the destination:<br />
<img class="size-full wp-image-121 alignnone" title="Apparent URL" src="http://www.lorrin.org/wp-uploads/2012/03/google_apparent_url.png" alt="" width="641" height="86" /></p>
<p>&nbsp;</p>
<p>But, upon click, URLs in Google search results change to go to Google first!</p>
<p><img class="size-full wp-image-122" title="Effective URL" src="http://www.lorrin.org/wp-uploads/2012/03/google_actual_url.png" alt="" width="643" height="86" /></p>
<p>&nbsp;</p>
<p><a title="Straight Google" href="https://userscripts.org/scripts/show/121261">Straight Google</a> removes this tracking from Google URLs across all Google products. Easy to install and no configuration needed, but you must install <a href="http://www.greasespot.net/">Greasemonkey</a> first.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/03/10/googles-click-tracking-and-how-to-disable-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixing key-repeat in OS X Lion (and restoring sanity for Vim keybindings) on a per-application basis</title>
		<link>http://www.lorrin.org/blog/2012/03/02/fixing-key-repeat-in-os-x-lion-and-restoring-sanity-for-vim-keybindings-on-a-per-application-basis/</link>
		<comments>http://www.lorrin.org/blog/2012/03/02/fixing-key-repeat-in-os-x-lion-and-restoring-sanity-for-vim-keybindings-on-a-per-application-basis/#comments</comments>
		<pubDate>Sat, 03 Mar 2012 05:06:15 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[IntelliJ]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=115</guid>
		<description><![CDATA[Starting with OS X Lion, holding down a key will bring up a menu of alternate characters rather than repeating the key. (This is a feature). There are many tips on how to re-enable key-repeat globally. But you can also control the behavior per-application (thanks, Egor Ushakov). This is handy for e.g. IntelliJ or RubyMine, <a href='http://www.lorrin.org/blog/2012/03/02/fixing-key-repeat-in-os-x-lion-and-restoring-sanity-for-vim-keybindings-on-a-per-application-basis/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Starting with OS X Lion, holding down a key will bring up a menu of alternate characters rather than repeating the key. (This is a <a href="https://support.apple.com/kb/HT4896">feature</a>). There are <a href="http://lifehacker.com/5826055/make-your-keyboard-keys-repeat-properly-when-held-down-in-mac-os-x-lion">many</a> <a href="http://osxdaily.com/2011/08/04/enable-key-repeat-mac-os-x-lion/">tips</a> on how to re-enable key-repeat <em>globally</em>. But you can also control the behavior <em>per-application</em> (<a href="http://www.belchak.com/2011/07/23/re-enabling-key-repeat-in-osx-lion/">thanks</a>, Egor Ushakov). This is handy for e.g. IntelliJ or RubyMine, or any other app that provides Vim-style keyboard bindings. The magic commands are:</p>
<pre class="brush:shell">% defaults write com.jetbrains.intellij ApplePressAndHoldEnabled -bool false
% defaults write com.jetbrains.rubymine ApplePressAndHoldEnabled -bool false</pre>
<p>But how do you figure out what the magic identifier for your application is? Simple: <code>defaults domains</code> will list them all:</p>
<pre class="brush:shell">defaults domains | gsed -e 's/, /\n/g' | grep jetbrains
com.jetbrains.intellij
com.jetbrains.intellij.ce
com.jetbrains.rubymine
jetbrains.communicator.core</pre>
<p>Note that in order to munge the commas into newlines for grep, gsed was required because <a href="http://www.lorrin.org/blog/2012/03/02/inserting-newlines-with-sed-on-os-x/">OS X default sed cannot (easily) insert newlines</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/03/02/fixing-key-repeat-in-os-x-lion-and-restoring-sanity-for-vim-keybindings-on-a-per-application-basis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Inserting newlines with sed on OS X</title>
		<link>http://www.lorrin.org/blog/2012/03/02/inserting-newlines-with-sed-on-os-x/</link>
		<comments>http://www.lorrin.org/blog/2012/03/02/inserting-newlines-with-sed-on-os-x/#comments</comments>
		<pubDate>Sat, 03 Mar 2012 04:58:46 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=113</guid>
		<description><![CDATA[Out of the box, inserting newlines does not work with sed on OS X: % echo foo,bar,baz &#124; sed -e 's/,/\n/g' foonbarnbaz The simple solution is to use GNU sed, which is already installed (as gsed), instead of the default BSD version: % echo foo,bar,baz &#124; gsed -e 's/,/\n/g' foo bar baz Alternatively, it is <a href='http://www.lorrin.org/blog/2012/03/02/inserting-newlines-with-sed-on-os-x/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Out of the box, inserting newlines does not work with sed on OS X:</p>
<pre class="brush:shell">% echo foo,bar,baz | sed -e 's/,/\n/g'
foonbarnbaz</pre>
<p>The simple solution is to use GNU sed, which is already installed (as gsed), instead of the default BSD version:</p>
<pre class="brush:shell">% echo foo,bar,baz | gsed -e 's/,/\n/g'
foo
bar
baz</pre>
<p>Alternatively, it is possible (though fiddly) to <a href="https://cafenate.wordpress.com/2010/12/05/newlines-in-sed-on-mac/">trick BSD sed into inserting newlines using extquotes</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/03/02/inserting-newlines-with-sed-on-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Random file selections with Python</title>
		<link>http://www.lorrin.org/blog/2012/02/21/random-file-selections-with-python/</link>
		<comments>http://www.lorrin.org/blog/2012/02/21/random-file-selections-with-python/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 18:28:50 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[ZSH]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=109</guid>
		<description><![CDATA[After my previous adventures in slicing and dicing a huge XML file, I wanted a means to randomly select files. But first, the directory had so many entries it was unwieldy on my laptop. The Python script below divvies the files up into directories of up to 1000 files each. (Adaptable to other contexts via <a href='http://www.lorrin.org/blog/2012/02/21/random-file-selections-with-python/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>After my previous adventures in <a title="Splitting large XML files with xml_split and sed (preserving root element and namespace declaration)" href="http://www.lorrin.org/blog/?p=93">slicing and dicing a huge XML</a> file, I wanted a means to randomly select files. But first, the directory had so many entries it was unwieldy on my laptop. The Python script below divvies the files up into directories of up to 1000 files each. (Adaptable to other contexts via slight tweaking of the filename regex and subdir name generation.)</p>
<pre class="brush:py">#!/usr/bin/python
import os
import re
where = '.' # source directory 

ls = os.listdir(where)
for f in ls:
  m = re.search('.*_COMM-([0-9]+).xml', f)
  if m:
    subdir = "%03d" % (int(m.group(1)) / 1000)
    try:
      os.mkdir(subdir)
    except OSError as e:
      pass
    os.rename(f, os.path.join(subdir, f))</pre>
<p>Now on to the random selection, again with Python:</p>
<pre class="brush:py">#!/usr/bin/python
import os
import random
import re
import sys

if len(sys.argv) &gt; 1:
  where = sys.argv[1]
else:
  where = '.' # source directory 

subdirs = filter(lambda x: re.search('^[0-9]*$', x), os.listdir(where))
subdir = os.path.join(where,random.choice(subdirs))
print os.path.join(subdir,random.choice(os.listdir(subdir)))</pre>
<p>A quick shell loop leverages the Python script to grab files and dump into a repository of test data. Works on ZSH, Bash, perhaps others:</p>
<pre class="brush:shell">for i in {1..250}; do cp $(./pick_a_file.py sub_dir_with_files) /destination/dir/filename_prefix_$(printf "%03d" $i).xml; done;</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/02/21/random-file-selections-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thunderbird still displays expunged IMAP messages</title>
		<link>http://www.lorrin.org/blog/2012/02/14/thunderbird-still-displays-expunged-imap-messages/</link>
		<comments>http://www.lorrin.org/blog/2012/02/14/thunderbird-still-displays-expunged-imap-messages/#comments</comments>
		<pubDate>Wed, 15 Feb 2012 06:11:12 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coping with Computers]]></category>
		<category><![CDATA[IMAP]]></category>
		<category><![CDATA[K-9 Mail]]></category>
		<category><![CDATA[Thunderbird]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=104</guid>
		<description><![CDATA[There is lots to be said about the intricacies of IMAP delete flags vs. actual expunging of deleted messages and the confusion caused when something is merely flagged for deletion and the user expected it to be really gone. This post is not about that. Everyone agrees that once a message is expunged, it definitely <a href='http://www.lorrin.org/blog/2012/02/14/thunderbird-still-displays-expunged-imap-messages/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>There is <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=220064">lots to be said</a> about the intricacies of IMAP <a href="http://kb.mozillazine.org/Deleting_messages_in_IMAP_accounts">delete flags vs. actual expunging</a> of deleted messages and the confusion caused when something is merely flagged for deletion and the user expected it to be really gone. This post is not about that. <em>Everyone agrees that once a message is expunged, it definitely should be gone.</em> But sometimes expunged messages still display in Thunderbird!</p>
<p>I often observe this:</p>
<ol>
<li>Delete message on the way to work using <a href="https://code.google.com/p/k9mail/">K-9</a> on my phone.</li>
<li>Arrive at work and message is gone from my Inbox in <a href="https://en.wikipedia.org/wiki/Mail_%28application%29">Mail.app</a></li>
<li>Come home, download new mail in <a href="https://www.mozilla.org/en-US/thunderbird/">Thunderbird</a> and see an Inbox full of undead messages.</li>
</ol>
<p>No amount of re-expunging and re-fetching mail helps. Grepping through the server-side Maildir shows the messages really are gone from the folders in which Thunderbird is still showing them.</p>
<p>It turns out the reason they are still displaying in Thunderbird is mundane client-side index corruption. To clean things up:</p>
<ol>
<li>Right-click on mailbox</li>
<li>Choose <tt>Properties...</tt></li>
<li>Click <tt>Repair Folder</tt></li>
<li>Rejoice at tidy mailbox</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/02/14/thunderbird-still-displays-expunged-imap-messages/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to treat a bare value as an Array in Ruby</title>
		<link>http://www.lorrin.org/blog/2012/02/08/how-to-treat-a-bare-value-as-an-array-in-ruby/</link>
		<comments>http://www.lorrin.org/blog/2012/02/08/how-to-treat-a-bare-value-as-an-array-in-ruby/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 05:40:43 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=99</guid>
		<description><![CDATA[Often Array(arg) is used for this, but is flawed. Note the last result when applied to a Hash: &#62; Array(42)  =&#62; [42] &#62; Array([1,2,3])  =&#62; [1, 2, 3] &#62; Array(nil)  =&#62; [] &#62; Array("foo")  =&#62; ["foo"] &#62; Array({"foo" =&#62; "bar", "biz" =&#62; "baz"})  =&#62; [["foo", "bar"], ["biz", "baz"]] What went wrong is that Array() calls <a href='http://www.lorrin.org/blog/2012/02/08/how-to-treat-a-bare-value-as-an-array-in-ruby/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Often <code>Array(arg)</code> is used for this, but is flawed. Note the last result when applied to a Hash:</p>
<pre class="brush:ruby">&gt; Array(42)
 =&gt; [42]
&gt; Array([1,2,3])
 =&gt; [1, 2, 3]
&gt; Array(nil)
 =&gt; []
&gt; Array("foo")
 =&gt; ["foo"]
&gt; Array({"foo" =&gt; "bar", "biz" =&gt; "baz"})
 =&gt; [["foo", "bar"], ["biz", "baz"]]</pre>
<p>What went wrong is that Array() calls the (now deprecated) <code>to_a</code> on each of its arguments. Hash has a custom <code>to_a</code> implementation with different semantics. Instead, do  this:</p>
<pre class="brush:ruby">class Array
  def self.wrap(args)
    return [] unless args
    args.is_a?(Array) ? args : [args]
  end
end</pre>
<p>That yields the expected results, even for Hashes:</p>
<pre class="brush:ruby">&gt; Array.wrap(42)
 =&gt; [42]
&gt; Array.wrap([1,2,3])
 =&gt; [1, 2, 3]
&gt; Array.wrap(nil)
 =&gt; []
&gt; Array.wrap("foo")
 =&gt; ["foo"]
&gt; Array.wrap({"foo" =&gt; "bar", "biz" =&gt; "baz"})
 =&gt; [{"foo"=&gt;"bar", "biz"=&gt;"baz"}]</pre>
<p>Use of <code>is_a?</code> is deliberate; duck-typing in this situation (<code>[:[], :each].all? { |m| args.respond_to? m }</code>) yields unexpected surprises since e.g. String is Enumerable and would not get wrapped.</p>
<p>For further discussion see Ruby-forum thread &#8220;<a href="http://www.ruby-forum.com/topic/145515">shortcut for x = [x] unless x.is_a?(Array)</a>&#8221; and StackOverflow &#8220;<a href="http://stackoverflow.com/questions/385912/ruby-object-to-a-replacement">Ruby: Object.to_a replacement</a>&#8220;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/02/08/how-to-treat-a-bare-value-as-an-array-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Splitting large XML files with xml_split and sed (preserving root element and namespace declaration)</title>
		<link>http://www.lorrin.org/blog/2012/02/08/splitting-large-xml-files-with-xml_split-and-sed/</link>
		<comments>http://www.lorrin.org/blog/2012/02/08/splitting-large-xml-files-with-xml_split-and-sed/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 04:47:42 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=93</guid>
		<description><![CDATA[Slicing up XML files is best done with an XML parser. (Regular expressions, csplit, etc. are too easily confused by arbitrary strings in CDATA sections.) xml_split (may be obtained with CPAN by installing XML::Twig) mostly does the trick. Given a file like: &#60;?xml version="1.0" encoding="UTF-8"?&#62; &#60;foo:Root xmlns:foo="http://www.foo.bar/fnarf/foo"&#62; &#60;foo:child&#62; ... &#60;/foo:child&#62; &#60;foo:child&#62; ... &#60;/foo:child&#62; &#60;/foo:Root&#62; &#8230;xml_split <a href='http://www.lorrin.org/blog/2012/02/08/splitting-large-xml-files-with-xml_split-and-sed/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Slicing up XML files is best done with an XML parser. (Regular expressions, csplit, etc. are too easily confused by arbitrary strings in CDATA sections.) <a href="http://search.cpan.org/perldoc?xml_split">xml_split</a> (may be obtained with CPAN by installing <a href="http://search.cpan.org/~mirod/XML-Twig-3.39/">XML::Twig</a>) <em>mostly</em> does the trick. Given a file like:</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;foo:Root xmlns:foo="http://www.foo.bar/fnarf/foo"&gt;
  &lt;foo:child&gt;
    ...
  &lt;/foo:child&gt;
  &lt;foo:child&gt;
    ...
  &lt;/foo:child&gt;
&lt;/foo:Root&gt;</pre>
<p>&#8230;xml_split can create many files, each containing:</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;foo:child&gt;
  ...
&lt;/foo:child&gt;</pre>
<p>However, this loses the namespace declaration and the enclosing root element. Luckily, a little sed magic can bring those back:</p>
<pre class="brush:shell">find . -name '*.xml' | xargs -n1 sed -e '1 a\
&lt;foo:Root xmlns:foo="http://www.foo.bar/fnarf/foo"&gt;
' -e '$ a\
&lt;/foo:Root&gt;
' -i ''</pre>
<p>find lists all the files, xargs invokes sed on them one by one (<code>-n1</code>), and sed adds the opening tag with namespace declaration after the first line (<code>1 a</code>) and the closing tag after the last line (<code>$ a</code>). Now each file looks like this:</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;foo:Root xmlns:foo="http://www.foo.bar/fnarf/foo"&gt;
  &lt;foo:child&gt;
    ...
  &lt;/foo:child&gt;
&lt;/foo:Root&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2012/02/08/splitting-large-xml-files-with-xml_split-and-sed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixing predicted runtime on APC UPS after replacing battery</title>
		<link>http://www.lorrin.org/blog/2011/11/27/fixing-predicted-runtime-on-apc-ups/</link>
		<comments>http://www.lorrin.org/blog/2011/11/27/fixing-predicted-runtime-on-apc-ups/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 09:44:48 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coping with Computers]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[apctest]]></category>
		<category><![CDATA[apcupsd]]></category>
		<category><![CDATA[ups]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=78</guid>
		<description><![CDATA[The battery in my APC Back-UPS BR 800 was worn out after years of service, so I bought a replacement from APC.com. However, apcupsd still reported zero runtime and erratic charge and load percentages. I did some manual recalibration attempts (charge fully, discharge completely using constant load). This got my estimated runtime from zero up <a href='http://www.lorrin.org/blog/2011/11/27/fixing-predicted-runtime-on-apc-ups/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>The battery in my APC Back-UPS BR 800 was worn out after years of service, so I bought a replacement from APC.com. However, <tt>apcupsd</tt> still reported zero runtime and erratic charge and load percentages. I did some manual recalibration attempts (charge fully, discharge completely using constant load). This got my estimated runtime from zero up to a few seconds, but the UPS was still not useful. A couple seconds of power outage would lead to bogus critically low battery readings and trigger automated shutdown. (Despite the fact that it took me about half an hour to complete the run-down under a similar load.)</p>
<p>This evening I was preparing for another recalibration attempt by looking for a way to disable the beeping when power is disconnected. It turns out <tt>apctest</tt> can <a href="http://jace.zaiki.in/2009/09/14/disabling-the-alarm-on-apc-upses">disable the alarm</a>. In the process, I noticed <tt>apctest</tt> can also read and write the battery date. On a whim, I updated the date. And, magic: <strong><em>Merely changing the battery date fixed the reported runtime, charge, and load percentages!</em></strong></p>
<p>Changing the battery date back to the original value did not bring the bogus readings back. Presumably the behavior is based on dead-reckoning of time elapsed since last battery change rather than any knowledge of what the current date actually is.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/11/27/fixing-predicted-runtime-on-apc-ups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>error: File name too long during Scala compile</title>
		<link>http://www.lorrin.org/blog/2011/11/17/error-file-name-too-long-during-scala-compile/</link>
		<comments>http://www.lorrin.org/blog/2011/11/17/error-file-name-too-long-during-scala-compile/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 20:17:45 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[ecryptfs]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=67</guid>
		<description><![CDATA[[ERROR] error: File name too long A common way to install Ubuntu is with an underlying ext4 file system and eCryptfs encrypted home directories. ext4, like many other file systems, has a maximum filename limit of 255 bytes. eCryptfs creates filenames much longer than the original. Compiled Scala classes tend to have long file names <a href='http://www.lorrin.org/blog/2011/11/17/error-file-name-too-long-during-scala-compile/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><code>[ERROR] error: File name too long</code></p>
<p>A common way to install Ubuntu is with an underlying ext4 file system and eCryptfs encrypted home directories. ext4, <a href="https://en.wikipedia.org/wiki/Comparison_of_file_systems" title="comparison of file systems">like many other file systems</a>, has a maximum filename limit of 255 bytes. eCryptfs <a href="https://bugs.launchpad.net/ecryptfs/+bug/344878">creates filenames much longer than the original</a>. Compiled Scala classes tend to have long file names since anonymous classes end up in their own files. Therefore, when compiling Scala projects within eCryptfs on ext4, it is <a href="https://github.com/dcaoyuan/nbscala/issues/9">easy to get file name too long</a> errors. <img src='http://www.lorrin.org/blog/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/11/17/error-file-name-too-long-during-scala-compile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala&#8217;s missing splat operator</title>
		<link>http://www.lorrin.org/blog/2011/10/04/scalas-missing-splat-operator/</link>
		<comments>http://www.lorrin.org/blog/2011/10/04/scalas-missing-splat-operator/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 07:38:16 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=59</guid>
		<description><![CDATA[Ruby, Python, and many other dynamic languages have a so-called splat operator that lets you easily invoke a function by providing a list of argument values: def f(x,y) x*y end &#62; fArgs = [6,7.0] =&#62; [6, 7.0] &#62; f(*fArgs) =&#62; 42.0 Scala does not have a splat operator per se, but you can achieve the <a href='http://www.lorrin.org/blog/2011/10/04/scalas-missing-splat-operator/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Ruby, Python, and many other dynamic languages have a so-called splat operator that lets you easily invoke a function by providing a list of argument values:</p>
<pre class="brush:ruby">def f(x,y)
  x*y
end

&gt; fArgs = [6,7.0]
=&gt; [6, 7.0]

&gt; f(*fArgs)
=&gt; 42.0</pre>
<p>Scala does not have a splat operator per se, but you can achieve the same effect without too much work. Sadly the syntax is different for fixed-<a href="https://secure.wikimedia.org/wikipedia/en/wiki/Arity">arity</a> and <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Variadic_function">variadic</a> functions.</p>
<h3>Scala splat for variadic functions</h3>
<p>For variadic functions there effectively is a splat operator. If you invoke a variadic function and append <code>:_*</code> to the argument the compiler will perform the splat:</p>
<pre class="brush:scala">&gt; def g(xs:Int*) = (0 /: xs) (_ + _)
g: (xs: Int*)Int

&gt; val gArgs = List(1,2,3,4)
gArgs: List[Int] = List(1, 2, 3, 4)

&gt; g(gArgs:_*)
res23: Int = 10</pre>
<h3>Scala splat for fixed-arity functions</h3>
<pre class="brush:scala">&gt; def f(x:Int, y:Double) = x * y
f: (x: Int, y: Double)Double

&gt; val fArgs = (6, 7.0)
fArgs: (Int, Double) = (6,7.0)

&gt; f _ tupled fArgs
res8: Double = 42.0</pre>
<p>Magic! The first part, <code>f _</code>, is the syntax for a partially applied function in which none of the arguments have been specified. This works as a mechanism to get a hold of the function object. <code>tupled</code> returns a new function which of arity-1 that takes a single arity-n tuple. It is defined in the Scala <a href="http://www.scala-lang.org/api/current/index.html#scala.Function$">Function object</a>,</p>
<p>However, given a <em>List</em> of arguments to pass to f, I&#8217;m not sure how to easily convert the List to a Tuple.</p>
<p>p.s. There&#8217;s a stackoverflow post about this called &#8220;<a href="http://stackoverflow.com/questions/3568002/scala-tuple-unpacking">scala tuple unpacking</a>.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/10/04/scalas-missing-splat-operator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Argumentless git pull and git push</title>
		<link>http://www.lorrin.org/blog/2011/10/03/argumentless-git-pull-and-git-push/</link>
		<comments>http://www.lorrin.org/blog/2011/10/03/argumentless-git-pull-and-git-push/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 05:55:38 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=56</guid>
		<description><![CDATA[Pulling and pushing with git can be a bit verbose.  This post explains how to get from git pull --rebase origin master and git push origin master to just typing git pull and git push. Rebase First, set rebase for every new upstream branch (Why rebase? It makes your history easier to understand.) git config <a href='http://www.lorrin.org/blog/2011/10/03/argumentless-git-pull-and-git-push/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Pulling and pushing with git can be a bit verbose.  This post explains how to get from <code>git pull --rebase origin master</code> and <code>git push origin master</code> to just typing <code>git pull</code> and <code>git push</code>.</p>
<h4>Rebase</h4>
<p>First, set <em>rebase</em> for every new upstream branch (Why rebase? It <a title="git pull with rebase" href="http://gitready.com/advanced/2009/02/11/pull-with-rebase.html">makes your history easier to understand</a>.)</p>
<p><code>git config --global branch.autosetuprebase always </code></p>
<p>This is explained in more detail (and with other helpful hints) in Mislav Marohnić&#8217;s post <a href="http://mislav.uniqpath.com/2010/07/git-tips/">A few git tips you didn&#8217;t know about</a>.</p>
<h4>Tracking</h4>
<p>Second, make <code>git push</code> only send the current branch to its matching upstream (aka tracking) branch. (Otherwise the default behavior is to push <em>all</em> branches that have the same name on both ends.)</p>
<p><code>git config --global push.default upstream</code></p>
<p>This is covered in some detail in Mark Longhair&#8217;s post <a href="http://longair.net/blog/2011/02/27/an-asymmetry-between-git-pull-and-git-push/">An asymmetry between git pull and push</a>.</p>
<p>On any existing branches, you can set up tracking by doing an explicit push:</p>
<p><code>git push -u origin <em>branchname</em></code></p>
<h4>Default refspec</h4>
<p>At this point you should be set according to all the tutorials I came across. In my experience, however, this only works for branches other than master. A plain <code>git push</code> on master yields the error:</p>
<p><code>fatal: The current branch master has multiple upstream branches, refusing to push.</code></p>
<p>The solution is to set the default refspec for git push. I&#8217;m unclear on why this needed for master but not for other branches.</p>
<p><code>git config remote.origin.push HEAD</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/10/03/argumentless-git-pull-and-git-push/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Fruitless Search for a Password Bookmarklet</title>
		<link>http://www.lorrin.org/blog/2011/06/15/a-fruitless-search-for-a-password-bookmarklet/</link>
		<comments>http://www.lorrin.org/blog/2011/06/15/a-fruitless-search-for-a-password-bookmarklet/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 07:41:43 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coping with Computers]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=53</guid>
		<description><![CDATA[Using a bookmarklet to store passwords is appealingly simple. Alas, after doing some digging, I couldn&#8217;t find any viable options. The first concern I came across is that it is important to use a hash algorithm that&#8217;s slow (e.g. bcrypt or scrypt). Otherwise it&#8217;s too easy to brute-force the master password based on a site <a href='http://www.lorrin.org/blog/2011/06/15/a-fruitless-search-for-a-password-bookmarklet/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Using a bookmarklet to store passwords is appealingly simple. Alas, after doing some digging, I couldn&#8217;t find any viable options.</p>
<p>The first concern I came across is that it is important to <a href="http://codahale.com/how-to-safely-store-a-password/">use a hash algorithm that&#8217;s </a><em><a href="http://codahale.com/how-to-safely-store-a-password/">slow</a></em> (e.g. <a href="https://secure.wikimedia.org/wikipedia/en/wiki/bcrypt">bcrypt</a> or <a href="http://www.tarsnap.com/scrypt.html">scrypt</a>)<em>.</em> Otherwise it&#8217;s too easy to brute-force the master password based on a site password. Suppose site you visit stores your password in plaintext and gets hacked. That breach then compromises your master password, even though only your site-specific password was revealed.</p>
<p>I couldn&#8217;t find a JavaScript implementation of scrypt, but I found a <a href="https://code.google.com/p/javascript-bcrypt/">JavaScript bcrypt implementation</a>. Better yet, I found a derivative that tidies up the first one, removing dependencies on e.g. <a href="http://www.clipperz.com/">ClipperZ</a>, and wraps it in a <a href="http://scripts.cwillu.com/passwords/">simple bookmarklet</a>. <a href="http://supergenpass.com/">SuperGenPass</a> provides a much more user-friendly bookmarklet, so I started gearing up to replace it&#8217;s MD5 hashing with bcrypt.</p>
<p>But, alas, SuperGenPass (and any other simple bookmarklet) is <a href="http://akibjorklund.com/2009/supergenpass-is-not-that-secure">not secure</a> in the face of a malicious website that contains JavaScript designed to sniff entry of the master password in to the bookmarklet. <a href="http://crypto.stanford.edu/PwdHash/">PwdHash</a> is a browser extension based approach from the Stanford Security Lab designed to combat the weaknesses of the bookmarklet based approach. Their paper, <a href="http://crypto.stanford.edu/PwdHash/pwdhash.pdf">Stronger Password Authentication Using Browser Extensions</a>, is interesting reading and explains a variety of ways to compromise a bookmarklet based approach. PwdHash has already spawned a number of ports to other browsers and mobile devices, but alas they&#8217;re all based on prototype code that uses HMAC-MD5 as the hashing algorithm (even though the paper points out PwdHash is a good candidate for a better hashing algorithm).</p>
<p>I was not able to find any PwdHash derivative that used bcrypt. I did find a simple <a href="http://blog.derekmauro.com/2011/04/how-i-manage-passwords.html">command-line tool based on scrypt</a>, but that&#8217;s not great if you don&#8217;t have easy access to your own computer.</p>
<p>Solutions like <a href="http://www.passpack.com/">PassPack</a> offer the potential to solve these problems (extension rather than bookmarklet, use of strong encryption rather than weak hashing), but have an Achilles heel of their own: <a href="http://maltainfosec.org/archives/88-PassPack-and-why-it-does-not-work.html">the service provider has the power to decrypt all your passwords</a>. For now I&#8217;ll stick with my <a href="../2011/03/30/introducing-moinmoin-client-crypt/">moinmoin-client-crypt</a> approach.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/06/15/a-fruitless-search-for-a-password-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Misadventures in Breaking Actors with Scala Self-Types</title>
		<link>http://www.lorrin.org/blog/2011/06/05/misadventures-in-breaking-actors-with-scala-self-types/</link>
		<comments>http://www.lorrin.org/blog/2011/06/05/misadventures-in-breaking-actors-with-scala-self-types/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 06:49:11 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[self-type]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=48</guid>
		<description><![CDATA[Quick refresher: self-types are commonly used when writing traits that want to proscribe that they get mixed in to a particular class. For example, the cake-pattern leverages them. In the example below, FooTrait specifies a self-type of FooTraitConfiguration to insure that it is mixed in to a class that provides the expected times val. import <a href='http://www.lorrin.org/blog/2011/06/05/misadventures-in-breaking-actors-with-scala-self-types/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Quick refresher: <a href="http://www.scala-lang.org/node/124">self-types</a> are commonly used when writing traits that want to proscribe that they get mixed in to a particular class. For example, the <a href="http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html">cake-pattern</a> leverages them. In the example below, <code>FooTrait</code> specifies a self-type of <code>FooTraitConfiguration</code> to insure that it is mixed in to a class that provides the expected <code>times</code> val.</p>
<pre>
<pre class="brush:scala">import actors.Actor
import actors.Actor._

trait FooTraitConfiguration { val times : Int }

trait FooTrait { self:FooTraitConfiguration =&gt;
  case object Ping
  case object Pong

  val a = actor {
    loop {
      react {
        case Ping =&gt;
          self ! Pong
        case Pong =&gt;
          for(_ &lt;- (1 to times)) { print(".") }
          System.out.println("pong.")
  } } }

  def ping = a ! Ping
  def pong = a ! Pong
}

class Foo extends FooTrait with FooTraitConfiguration { @Override val times = 5 }</pre>
</pre>
<p>But, alas, this fails to compile:</p>
<pre>error: value ! is not a member of FooTrait with FooTraitConfiguration
self ! Pong</pre>
<p>It seems that the self-trait has broken the Actor API! And indeed, it has. Because self-traits are not usually specified with <code>self</code>! It should have been:<br />
<code><strong>this</strong>:FooTraitConfiguration =&gt;</code></p>
<p>The self-type means that within <code>FooTrait</code> the type of <code>this</code> is considered to be <code>FooTrait with FooTraitConfiguration</code>. Using a word other than <code>this</code> <a href="http://stackoverflow.com/questions/4017357/difference-between-this-and-self-in-self-type-annotations/4018995#4018995">additionally sets up an alias to that type for e.g. use within nested classes</a>. And there&#8217;s the rub: Actors depend on a method named <code>self</code> which is shadowed when the alias to the type is named <code>self</code>.</p>
<p>Note to self: <strong>Don&#8217;t use <code>self</code> when specifying self types!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/06/05/misadventures-in-breaking-actors-with-scala-self-types/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Untangling multi-threaded log files</title>
		<link>http://www.lorrin.org/blog/2011/04/12/untangling-multi-threaded-log-files/</link>
		<comments>http://www.lorrin.org/blog/2011/04/12/untangling-multi-threaded-log-files/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 06:59:45 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[log file]]></category>
		<category><![CDATA[misc-tools-scripts]]></category>
		<category><![CDATA[multi-threading]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[token_indenter.py]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=16</guid>
		<description><![CDATA[Yesterday I needed to decipher a log file in which a dozen threads were simultaneously logging messages. Surely there must be tools for this out there. But I couldn&#8217;t find one, so I wrote a Python script to indent each line differently based on thread id. I then looked at it in LibreOffice, but just <a href='http://www.lorrin.org/blog/2011/04/12/untangling-multi-threaded-log-files/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Yesterday I needed to decipher a log file in which a dozen threads were simultaneously logging messages. Surely there must be tools for this out there. But I couldn&#8217;t find one, so I wrote a Python script to indent each line differently based on thread id. I then looked at it in <a href="http://www.libreoffice.org/">LibreOffice</a>, but just reading on the terminal would have sufficed. Here&#8217;s a trivial demo:</p>
<pre>2011-04-11 09:40:12,004 [INFO] [http-3] Hello
2011-04-11 09:40:13,554 [DEBUG] [http-1] Wikipedia
(pronounced /ˌwɪkɨˈpiːdi.ə/ WIK-i-PEE-dee-ə)
2011-04-11 09:40:13,605 [INFO] [http-2] PCC Natural Markets
2011-04-11 09:40:13,688 [INFO] [http-3] World
2011-04-11 09:40:14,015 [INFO] [http-2] began as a food-buying club of 15 families in 1953.
2011-04-11 09:40:16,032 [INFO] [http-1] is a multilingual, web-based, free-content encyclopedia project based on an openly editable model
2011-04-11 09:40:17,775 [INFO] [http-2] Today, it's the largest consumer-owned natural food retail co-operative in the United States.</pre>
<p>becomes:</p>
<pre>09:40:12,004	Hello
09:40:13,554		Wikipedia
09:40:13,554		(pronounced /ˌwɪkɨˈpiːdi.ə/ WIK-i-PEE-dee-ə)
09:40:13,605			PCC Natural Markets
09:40:13,688	World
09:40:14,015			began as a food-buying club of 15 families in 1953.
09:40:16,032		is a multilingual, web-based, free-content encyclopedia project based on an openly editable model
09:40:17,775			Today, it's the largest consumer-owned natural food retail co-operative in the United States.
            	http-3	http-1	http-2</pre>
<p>Just read down the columns vertical for a clear chain of events on each thread. Code below is <a href="https://github.com/lorrin/misc-tools-scripts/blob/master/token_indenter.py">maintained on GitHub</a>.</p>
<pre class="brush:py">#!/usr/bin/env python

# Looks at token in a particular position in each line and indents the line
# differently for each unique identifier found in the file. For example, given
# a log file which contains a thread identifier, contents for each thread will
# be separated out into distinct columns.
#
# Lines not matching the pattern (e.g. stack traces) are presumed to have
# occurred at the time of and belong to the same identifier as the preceding line.
#
# Default pattern is: &lt;date&gt; &lt;stamp&gt; ignored [thread_id] &lt;message&gt;
# Yielding output: &lt;stamp&gt;&lt;tabs&gt;&lt;message&gt;
#
# An alternate regular expression can be supplied on the command line; it must
# include named capture groups 'stamp', 'id', and 'message'. The default regex
# is: ^\S+ (?P&lt;stamp&gt;\S+) \S+ \[(?P&lt;id&gt;[^\]]+)\] (?P&lt;message&gt;.*)
#
# If the input contains very long lines it can be helpful to truncate them
# beforehand by e.g. piping through awk '{print substr($0,0,400)}'

import sys,re
if len(sys.argv) &gt; 1:
  pattern = re.compile(sys.argv[1])
else:
  pattern = re.compile('^\S+ (?P&lt;stamp&gt;\S+) \S+ \[(?P&lt;id&gt;[^\]]+)\] (?P&lt;message&gt;.*)')

delimiter='\t'
max_level = 1
categories = {}
legend = None
indent = ""
stamp = ""

try:
  for line in [l.strip() for l in sys.stdin]:
    m = pattern.match(line)
    if m:
      stamp,identifier,message = [m.group(x) for x in ['stamp','id','message']]
      indent = categories.get(identifier)
      if not legend:
        legend = " " * len(stamp)
      if not indent:
        indent = delimiter * max_level
        categories[identifier] = indent
        max_level += 1
        legend += delimiter + identifier
      print stamp + indent + message
    else:
      # carry over stamp and indent from previous line
      print stamp + indent + line

  print legend
except IOError:
  pass</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/04/12/untangling-multi-threaded-log-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Snipping log files by time</title>
		<link>http://www.lorrin.org/blog/2011/04/12/snipping-log-files-by-time/</link>
		<comments>http://www.lorrin.org/blog/2011/04/12/snipping-log-files-by-time/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 06:59:31 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[by_time.py]]></category>
		<category><![CDATA[log file]]></category>
		<category><![CDATA[misc-tools-scripts]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=38</guid>
		<description><![CDATA[Grepping through log files for lines that match a timestamp is fiddly. It&#8217;s hard to catch multi-line entries (e.g. stack traces) and to craft a regex that captures an exact time range. I wrote a little Python script to simpify the process. Usage: &#60;example.log&#124; ./by_time.py 9:40 9:44:15 Code below is maintained on GitHub. #!/usr/bin/env python <a href='http://www.lorrin.org/blog/2011/04/12/snipping-log-files-by-time/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Grepping through log files for lines that match a timestamp is fiddly. It&#8217;s hard to catch multi-line entries (e.g. stack traces) and to craft a regex that captures an exact time range. I wrote a little Python script to simpify the process.</p>
<p>Usage:</p>
<pre class="brush:shell"> &lt;example.log| ./by_time.py 9:40 9:44:15</pre>
<p>Code below is <a href="https://github.com/lorrin/misc-tools-scripts/blob/master/by_time.py">maintained on GitHub</a>.</p>
<pre class="brush:py">#!/usr/bin/env python

# Selects time range from a log file. Lines with no time (e.g. stack traces)
# are presumed to have occurred at the time of the preceding line.
#
# Assumes first time-like phrase on a line is the timestamp for that line.
#
# Assumes time format is pairs of digits separated by colons with optional , or
# . initiated suffix. E.g. HH:mm:ss,SSS, HH:mm, etc.
#
# Does not strip blank lines; just use awk 'NF&gt;0' for that.

import sys,re
time_pattern = re.compile("(?:^|.*?\D)(\d{1,2}(?::\d{2})+(?:[,.]\d+)?)")
fields_pattern = re.compile("[:,.]")

if len(sys.argv) &lt; 3:
  print &gt;&gt; sys.stderr, "Please specify start and end times (e.g. %s 13:50 14:10:01,101)." % sys.argv[0]
  exit(1)

for item,index in [["start time",1],["end time",2]]:
  if not time_pattern.match(sys.argv[index]):
    raise ValueError("Cannot parse %s: %s" % (item, sys.argv[index]))

start,end = [[int(x) for x in re.split(fields_pattern, s)] for s in sys.argv[1:3]]
too_soon = True

try:
  for line in sys.stdin:
    line = line.strip()
    m = time_pattern.match(line)
    if m:
      t = [int(x) for x in re.split(fields_pattern,m.group(1))]
      if t &gt;= end:
        break
      elif too_soon and t &gt;= start:
        too_soon = False

    if not too_soon:
      print line
except IOError:
  pass</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/04/12/snipping-log-files-by-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Taming Firefox + Adblock with browser.sessionstore.max_concurrent_tabs</title>
		<link>http://www.lorrin.org/blog/2011/04/04/firefox-adblock-memory-leak/</link>
		<comments>http://www.lorrin.org/blog/2011/04/04/firefox-adblock-memory-leak/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 04:27:00 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coping with Computers]]></category>
		<category><![CDATA[Adblock Plus]]></category>
		<category><![CDATA[Firefox]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=13</guid>
		<description><![CDATA[I tend to have lots of browser tabs open. Even more so with Firefox 4&#8242;s Panorama feature, which I find handy despite the frustrating limitation that tab groups cannot be moved between windows. Alas, having many tabs open is suspected to trigger/exacerbate a Firefox memory leak when Adblock Plus is running. My own informal testing <a href='http://www.lorrin.org/blog/2011/04/04/firefox-adblock-memory-leak/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I tend to have lots of browser tabs open. Even more so with Firefox 4&#8242;s <a href="http://www.azarask.in/blog/post/designing-tab-candy/">Panorama</a> feature, which I find handy despite the frustrating limitation that <a href="https://support.mozilla.com/hi-IN/questions/796129">tab groups cannot be moved between windows</a>. Alas, having many tabs open is suspected to trigger/exacerbate a <a href="https://adblockplus.org/forum/viewtopic.php?f=1&amp;t=7006">Firefox memory leak when Adblock Plus is running</a>. My own informal testing corroborates this.</p>
<p>In Firefox 3.6 I had used <a href="https://addons.mozilla.org/en-US/firefox/addon/bartab/">BarTab</a>, a great plug-in that allowed unloading tabs without closing them to reclaim memory. Alas, it is <a href="https://github.com/philikon/BarTab/wiki/FAQ">not yet compatible with Firefox 4</a>.</p>
<p>But it turns out Firefox 4 has a new setting (called <a href="http://blog.zpao.com/post/1140456188/cascaded-session-restore-a-hidden-bonus">Cascaded Session Restore</a>) that provides a reasonable work-around. In <code>about:config</code> set</p>
<p><code>browser.sessionstore.max_concurrent_tabs=0</code></p>
<p>&#8230;and  then, when closed and re-opened, Firefox will not load any tab until  you click on it. Now it&#8217;s extremely fast to quit, restart, and continue  on with reduced memory usage.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/04/04/firefox-adblock-memory-leak/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSPWiki-translate-perl and HTML::WikiConverter-MoinMoin</title>
		<link>http://www.lorrin.org/blog/2011/03/31/jspwiki-translate-perl-and-htmlwikiconverter-moinmoin/</link>
		<comments>http://www.lorrin.org/blog/2011/03/31/jspwiki-translate-perl-and-htmlwikiconverter-moinmoin/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 08:03:59 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[JSPWiki]]></category>
		<category><![CDATA[MoinMoin]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[wiki]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=9</guid>
		<description><![CDATA[moinmoin-client-crypt was the fun part of a recent Wiki migration project I did. The tedious prelude was getting the content out of an aging JSPWiki version and into MoinMoin. After some aborted attempts at translating the JSPWiki source from scratch, I decided the path of least resistance would be to leverage HTML::WikiConverter to translate the <a href='http://www.lorrin.org/blog/2011/03/31/jspwiki-translate-perl-and-htmlwikiconverter-moinmoin/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lorrin.org/blog/2011/03/30/introducing-moinmoin-client-crypt/">moinmoin-client-crypt</a> was the fun part of a recent Wiki migration project I did. The tedious prelude was getting the content out of an aging <a href="http://www.jspwiki.org/">JSPWiki</a> version and into <a href="http://moinmo.in/">MoinMoin</a>.</p>
<p>After some aborted attempts at translating the JSPWiki source from scratch, I decided the path of least resistance would be to leverage <a href="http://search.cpan.org/dist/HTML-WikiConverter/lib/HTML/WikiConverter.pm">HTML::WikiConverter</a> to translate the HTML output of JSPWiki. This turned out to be time consuming as well. To anyone else going down this path I offer up:</p>
<ol>
<li><a href="https://github.com/lorrin/HTML-WikiConverter-MoinMoin">A patched version of HTML::WikiConverter-MoinMoin</a> that includes fixes for intra-wiki links, inline images, horizontal rules, and definition lists.</li>
<li>A collection of scripts, dubbed <a href="https://github.com/lorrin/JSPWiki-translate-perl">JSPWiki-translate-perl</a>, for retrieving HTML from JSPWiki, pre-processing it to make it more palatable for HTML::WikiConverter, and for generating a MoinMoin-style directory layout to contain it.</li>
</ol>
<p>The original author of HTML::WikiConverter-MoinMoin seems to have abandoned it. I can sympathize; I certainly hope to avoid translating another Wiki any time soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/03/31/jspwiki-translate-perl-and-htmlwikiconverter-moinmoin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing moinmoin-client-crypt</title>
		<link>http://www.lorrin.org/blog/2011/03/30/introducing-moinmoin-client-crypt/</link>
		<comments>http://www.lorrin.org/blog/2011/03/30/introducing-moinmoin-client-crypt/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 23:21:15 +0000</pubDate>
		<dc:creator>lorrin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[MoinMoin]]></category>
		<category><![CDATA[moinmoin-client-crypt]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[wiki]]></category>

		<guid isPermaLink="false">http://www.lorrin.org/blog/?p=5</guid>
		<description><![CDATA[I just posted the first release of moinmoin-client-crypt to GitHub. As way of introduction, here&#8217;s an excerpt from the readme: moinmoin-client-crypt provides client-side encryption/decryption of MoinMoin wiki pages (or portions thereof). It adds encrypt/decrypt buttons to the edit screen, providing an easy mechanism to secure all or a portion of the content. Encryption is via <a href='http://www.lorrin.org/blog/2011/03/30/introducing-moinmoin-client-crypt/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I just posted the first release of <a href="https://github.com/lorrin/moinmoin-client-crypt">moinmoin-client-crypt</a> to GitHub. As way of introduction, here&#8217;s an excerpt from the readme:</p>
<p><strong>moinmoin-client-crypt provides client-side encryption/decryption of MoinMoin wiki pages (or portions thereof). It adds encrypt/decrypt buttons to the edit screen, providing an easy mechanism to secure all or a portion of the content.</strong> Encryption is via Chris Veness&#8217; Javascript AES implementation (256 bit key, CTR mode).</p>
<p>Installation involves dropping a couple JavaScript files into the appropriate MoinMoin directory and tweaking the theme init file to reference them. Full functionality with modern and classic themes, perhaps slightly degraded on others. It shouldn&#8217;t take much tweaking to adapt to other themes; patches and bug reports are welcome!</p>
<p>The client-side JavaScript approach provides some security if the server were to be seized: the AES ciphertext should be extremely difficult to crack. Also, once the browser is closed on the client side, there should be no trace left of the plaintext. However, if the server were compromised it would be easy to replace moinmoin-client-crypt with a trojan horse if a malicious person were to gain control of the client, they could easily install e.g. a keylogger you have to trust your client machine, your browser, your connection to the server, and the integrity of the server, as explained <a title="Final post on Javascript crypto" href="http://rdist.root.org/2010/11/29/final-post-on-javascript-crypto/">here</a> by Nate Lawson. The need for client-side security should be obvious; the server and connection must be trusted not to send/inject a modified version of the script.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorrin.org/blog/2011/03/30/introducing-moinmoin-client-crypt/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

