<?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>Adrian Smith&#039;s Blog</title>
	<atom:link href="http://www.17od.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.17od.com</link>
	<description></description>
	<lastBuildDate>Sun, 30 Oct 2016 21:04:27 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.2</generator>
	<item>
		<title>An Introduction to Gnuplot</title>
		<link>http://www.17od.com/2016/10/30/an-introduction-to-gnuplot/</link>
		<pubDate>Sun, 30 Oct 2016 21:04:27 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=805</guid>
		<description><![CDATA[Introduction Gnuplot is an incredibly powerful and useful utility for presenting data in graphical format. In this post I&#8217;ll cover a very simple usecase that involves graphing the size of a database over a period of time. Installing On Linux &#8230; <a href="http://www.17od.com/2016/10/30/an-introduction-to-gnuplot/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Gnuplot is an incredibly powerful and useful utility for presenting data in graphical format. In this post I&#8217;ll cover a very simple usecase that involves graphing the size of a database over a period of time.</p>
<h2>Installing</h2>
<p>On Linux use your normal package manager, e.g.</p>
<pre># Debian based...
apt-get install gnuplot

# Redhat based...
yum install gnuplot</pre>
<p>The easiest way to install gnuplot on OS X is using brew. Gnuplot requires X11 to display graphs so to install it use,</p>
<pre>brew install gnuplot --with-x11</pre>
<p>If X11 support isn&#8217;t available gnuplot will fail to display graphs with the error,</p>
<pre>WARNING: Plotting with an 'unknown' terminal.
No output will be generated. Please select a terminal with 'set terminal'.</pre>
<p>If this happens uninstall and then reinstall with X11 support.</p>
<h2>Basic Usage</h2>
<p>In the example below I&#8217;ll use a data file called &#8216;<a href="/uploads/db_size.dat">db_size.dat</a>&#8216;. Each line in this file records the size of a database at an hourly interval.</p>
<p>The most basic gnuplot command to graph this data would be,</p>
<pre><strong>gnuplot -p -e "plot 'db_size.dat'"</strong></pre>
<p>The -p parameter (short for persist) leaves the window containing the graph open after gnuplot finishes.</p>
<p>The -e parameter is the command to pass to gnuplot. The command &#8220;plot &#8216;db_size.dat'&#8221; means plot a graph using the data in db_size.dat.</p>
<p>Running this command will open a a window with this graph.</p>
<p><a href="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph1.png"><img class="aligncenter size-medium wp-image-811" src="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph1-300x227.png" alt="Graph 1" width="300" height="227" srcset="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph1-300x227.png 300w, http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph1.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Depending on your requirements this simple graph may be absolutely fine. However if you&#8217;d like to polish it up there are a few changes we can make.</p>
<p>First of all lets give the graph a title.</p>
<pre><strong>gnuplot -p -e "set title 'Database Size'; plot 'db_size.dat'"</strong></pre>
<p><a href="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph2.png"><img class="aligncenter size-medium wp-image-812" src="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph2-300x227.png" alt="Graph 2" width="300" height="227" srcset="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph2-300x227.png 300w, http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph2.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a><br />
At this stage the command line is getting a little long. This is where gnuplot command files come into play. Each file is basically a list of commands.</p>
<p>This command file is called &#8216;db_size.gnuplot&#8217;,</p>
<pre><strong>set title 'Database Size'
plot 'db_size.dat'</strong></pre>
<p>The command file name is passed to gnuplot as a parameter,</p>
<pre><strong>gnuplot -p db_size.gnuplot</strong></pre>
<p>Lets add axis labels and give the key a name.</p>
<pre><strong>set title 'Database Size'</strong>
<strong>set xlabel "Time"</strong>
<strong>set ylabel "Size (bytes)"</strong>
<strong>plot 'db_size.dat' title 'Database Size'</strong></pre>
<p><a href="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph3.png"><img class="aligncenter size-medium wp-image-813" src="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph3-300x227.png" alt="Graph 3" width="300" height="227" srcset="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph3-300x227.png 300w, http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph3.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>The dots can be difficult to follow when the they&#8217;re spaced out so lets use a line instead.</p>
<pre><strong>set title 'Database Size'</strong>
<strong>set xlabel "Time"</strong>
<strong>set ylabel "Size (bytes)"</strong>
<strong>plot 'db_size.dat' title 'Database Size' with line</strong></pre>
<p><a href="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph4.png"><img class="aligncenter size-medium wp-image-814" src="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph4-300x227.png" alt="Graph 4" width="300" height="227" srcset="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph4-300x227.png 300w, http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph4.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>The last change I&#8217;d like to make is to make the Y-axis scale more readable by converting bytes to gigabytes.</p>
<pre><strong>set title 'Database Size'</strong>
<strong>set xlabel "Time"</strong>
<strong>set ylabel "Size (GB)"</strong>
<strong>plot 'db_size.dat' using ($1/1000000000) title 'Database Size' with line</strong></pre>
<p><a href="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph5.png"><img class="aligncenter size-medium wp-image-815" src="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph5-300x227.png" alt="Graph 5" width="300" height="227" srcset="http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph5-300x227.png 300w, http://www.17od.com/wordpress/wp-content/uploads/2016/10/graph5.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Finally lets save the graph to a PNG rather than displaying it on screen.</p>
<pre><strong>set term png</strong>
<strong>set output "db_size.png"</strong>
<strong>set title 'Database Size'</strong>
<strong>set xlabel "Time"</strong>
<strong>set ylabel "Size (GB)"</strong>
<strong>plot 'db_size.dat' using ($1/1000000000) title 'Database Size' with line</strong></pre>
<p>This saves the graph to a file called db_size.png in the current directory.</p>
<h2>Going a Little Further</h2>
<p>In the previous example there was one data value recorded at fixed intervals, i.e. hourly. But what if the same data is collected at irregular intervals? To reliably graph this data we need to record the time each data point is recorded, <a href="/uploads/db_size_with_time.dat">db_size_with_time.dat</a>. In this file the first column is seconds since the epoch. Gnuplot can parse this using the &#8216;set xdata&#8217; command. Here&#8217;s the full command file,</p>
<pre><strong>set title 'Database Size'
set xlabel "Time"
set ylabel "Size (GB)"
set key off
set xdata time
set timefmt "%s"
set xtics format "%H"
plot 'db_size_with_time.dat' using 1:($2/1000000000) with line</strong></pre>
<p>&#8216;set key off&#8217; turns off the key. Its not very useful in this graph.</p>
<p>&#8216;set xdata time&#8217; parses the X axis data as a time.</p>
<p>&#8216;set timefmt &#8220;%s&#8221;&#8216; means read time values as seconds since the epoch.</p>
<p>&#8216;set xtics form &#8220;%H&#8221;&#8216; means write the hour to the X axis</p>
<p><a href="http://www.17od.com/wordpress/wp-content/uploads/2016/10/db_size_with_time.png"><img class="aligncenter size-medium wp-image-828" src="http://www.17od.com/wordpress/wp-content/uploads/2016/10/db_size_with_time-300x225.png" alt="Database Size with Time" width="300" height="225" srcset="http://www.17od.com/wordpress/wp-content/uploads/2016/10/db_size_with_time-300x225.png 300w, http://www.17od.com/wordpress/wp-content/uploads/2016/10/db_size_with_time.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>This post barely scratches the surface of what can be achieved using gnuplot. It&#8217;s really an amazing piece of software.</p>
<p>For more information:</p>
<ul>
<li><a href="http://gnuplot.sourceforge.net/demo/">Demo scripts for gnuplot version 5</a></li>
<li><a href="http://gnuplot.sourceforge.net/documentation.html">Official gnuplot Documentation</a></li>
</ul>
]]></content:encoded>
			</item>
		<item>
		<title>The Irish Constitution Git Repository</title>
		<link>http://www.17od.com/2015/05/09/the-irish-constitution-git-repository/</link>
		<pubDate>Sat, 09 May 2015 18:22:17 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=785</guid>
		<description><![CDATA[The Irish Constitution and each of it&#8217;s amendments are published by the Office of the Attorney General on the Irish Statute Book website. To date there have been thirty-three amendments proposed with twenty-seven being passed. Each amendment describes the change &#8230; <a href="http://www.17od.com/2015/05/09/the-irish-constitution-git-repository/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>The Irish Constitution and each of it&#8217;s amendments are published by the Office of the Attorney General on the <a href="http://www.irishstatutebook.ie/en/constitution/">Irish Statute Book</a> website. To date there have been thirty-three amendments proposed with twenty-seven being passed.</p>
<p>Each amendment describes the change being proposed like this (from the second amendment in respect of a change being proposed to article 25),</p>
<blockquote><p>In sub-section 1° of section 2, the deletion of the word “<span class="amended">five</span>” and the insertion in its place of the words “<span class="amended">the fifth</span>”, and the deletion of the words “<span class="amended">seven days</span>” and the insertion in their place of the words “<span class="amended">the seventh day</span>”</p></blockquote>
<p>While its accurate it&#8217;s not very easy to see the impact of the change in the context of the document.</p>
<p>In the software engineering world we store code, which is just text, in source control. Using the tools provided by the source control system we can compare two versions of a document to see how they differ.</p>
<p>To get to the point where I could compare different versions of the constitution I assembled a text version of the document and created a commit for each amendment. The end result is this git repository, <a href="https://github.com/adrian/irish-constitution">https://github.com/adrian/irish-constitution</a>.</p>
<p>Every amendment up to and including amendment thirty-three is included.</p>
<p>For the sake of completeness I included the <a href="http://en.wikipedia.org/wiki/Constitution_of_Ireland#Transitory_provisions">transitory articles</a> 51 to 64 and 34a. Rather than including the transitory sub-sections 29.7.3, 29.7.4 and 29.7.5 (from amendment 19) I made the changes directly to articles 2 and 3.</p>
<p>Each commit of <a href="https://github.com/adrian/irish-constitution/commits/master/constitution.md">constitution.md</a> represents an amendment. By opening any of these commits we can see how that amendment changed the constitution. For example, <a href="https://github.com/adrian/irish-constitution/commit/b5dfd3d904fd08ad527b9242b7129003e8e03f82#diff-26f07ab58c6acb6da1a3d79f4c13125d">amendment thirty-three looks like this</a>.</p>
<p>The left column is the constitution before amendment thirty-three, the right is after amendment thirty-three. Red lines are deleted or changed with dark red words deleted. Green lines are added or changed with dark green words added. By showing the two versions of the document, before and after, and highlighting the changes the effect of the amendment should be easier to understand.</p>
<p>To round it off there are two pending changes (pull requests) for each of the upcoming referendums on the 22nd May 2015,</p>
<ul>
<li><a href="https://github.com/adrian/irish-constitution/pull/1">Thirty-fourth Amendment of the Constitution, Act 2015</a></li>
<li><a href="https://github.com/adrian/irish-constitution/pull/2">Thirty-fifth Amendment of the Constitution, Act 2015</a></li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			</item>
		<item>
		<title>Installing Android Studio on Debian Wheezy</title>
		<link>http://www.17od.com/2014/11/12/installing-android-studio-on-debian-wheezy/</link>
		<comments>http://www.17od.com/2014/11/12/installing-android-studio-on-debian-wheezy/#comments</comments>
		<pubDate>Wed, 12 Nov 2014 19:44:33 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=775</guid>
		<description><![CDATA[Android Studio is the new IntelliJ IDEA based Android IDE. It succeeds the current Eclipse based IDE. Android Studio requires Oracle Java 1.6 or later. It won&#8217;t work with OpenJDK. Installing Oracle Java 1.7 These instructions describe how to install &#8230; <a href="http://www.17od.com/2014/11/12/installing-android-studio-on-debian-wheezy/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Android Studio is the new IntelliJ IDEA based Android IDE. It succeeds the current Eclipse based IDE.</p>
<p>Android Studio requires Oracle Java 1.6 or later. It won&#8217;t work with OpenJDK.</p>
<h3>Installing Oracle Java 1.7</h3>
<p>These instructions describe how to install Oracle Java using <a title="java-common" href="https://packages.debian.org/wheezy/java-common">java-common</a>. java-common only works with Java 1.6 or 1.7. It doesn&#8217;t work with Java 8.</p>
<ul>
<li>Download the latest 1.7 JDK from <a title="http://www.oracle.com/technetwork/java/javase/downloads/index.html" href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">http://www.oracle.com/technetwork/java/javase/downloads/index.html</a>. To find the tarball follow the links &#8220;Previous Releases &#8211; Java Archive&#8221; -&gt; &#8220;Java SE 7&#8221; -&gt; &#8220;Java SE Development Kit 7u..&#8221;. You&#8217;ll need the tarball not the RPM, e.g. jdk-7u67-linux-x64.tar.gz. Note: you&#8217;ll need an Oracle account to download archive versions of Java (those &lt; Java 8).</li>
</ul>
<ul>
<li>Install java-common<br />
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p># apt-get install java-common</p></blockquote>
</li>
<li>Create a deb file using the Java tarball,<br />
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<pre>$ make-jpkg &lt;downloaded tarball&gt;</pre>
</blockquote>
</li>
</ul>
<ul>
<li>Install the resulting package (your deb file name will likely be different),<br />
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<pre># deb -i oracle-j2sdk1.7_1.7.0+update67_amd64.deb</pre>
</blockquote>
</li>
<li>Update your java links to point at this new Oracle Java package. To find the name of this package take a look in /usr/lib/jvm/. There should be a directory named j2sdk1.7-oracle (or something similar). Use this directory name in a call to update-java-alternatives.<br />
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<pre># update-java-alternatives -s j2sdk1.7-oracle</pre>
</blockquote>
</li>
<li>Test your system is using the correct version of Java using,<br />
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<pre>$ java -version
 java version "1.7.0_67"
 Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
 Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)</pre>
</blockquote>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<pre>$ javac -version
 javac 1.7.0_67</pre>
</blockquote>
</li>
</ul>
<h3>Install the Android SDK Tools</h3>
<p>The Android SDK Tools package contains the SDK Manager. You&#8217;ll need this to download one or more SDKs.</p>
<p>Download &#8220;SDK Tools Only&#8221; from <a title="https://developer.android.com/sdk/index.html" href="https://developer.android.com/sdk/index.html">https://developer.android.com/sdk/index.html</a>. Extract the downloaded file to your applications directory, e.g. ~/apps/.</p>
<h3>Install Android Studio</h3>
<p>Download Android Studio from <a title="http://developer.android.com/sdk/installing/studio.html" href="http://developer.android.com/sdk/installing/studio.html">http://developer.android.com/sdk/installing/studio.html</a>.</p>
<p>Unzip the downloaded file to whereever you keep your apps, e.g. ~/apps/.</p>
<p>To start Android Studio run &lt;install dir&gt;/android-studio/bin/studio.sh.</p>
<p>Configure the location of your Android SDK by selecting &#8220;Configure&#8221; -&gt; &#8220;Project Defaults&#8221; -&gt; &#8220;Project Structure&#8221; -&gt; &#8220;Android SDK Location&#8221;. Enter the directory where you extracted the Android SDK Tools.</p>
<p>I find it useful to create a launcher icon. This way I can launch Android Studio by clicking Alt-F1 and entering the first few characters of the app name. To create a launcher icon from the Welcome splash screen select &#8220;Configure&#8221; -&gt; &#8220;Create Desktop Entry&#8221;.</p>
<h3>References</h3>
<ul>
<li><a title="https://wiki.debian.org/Java/Sun" href="https://wiki.debian.org/Java/Sun">https://wiki.debian.org/Java/Sun</a></li>
<li><a title="http://developer.android.com/sdk/installing/studio.html" href="http://developer.android.com/sdk/installing/studio.html">http://developer.android.com/sdk/installing/studio.html</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.17od.com/2014/11/12/installing-android-studio-on-debian-wheezy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Announcing Feed2me</title>
		<link>http://www.17od.com/2013/11/26/announcing-feed2me/</link>
		<pubDate>Tue, 26 Nov 2013 20:44:18 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=760</guid>
		<description><![CDATA[This is just a quick post to announce the release of Feed2me, a little spare-time project I&#8217;ve been working on recently. Feed2me monitors your favourite RSS/Atom feeds and sends you an email when new entries are posted. It runs on &#8230; <a href="http://www.17od.com/2013/11/26/announcing-feed2me/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>This is just a quick post to announce the release of <a href="https://github.com/adrian/feed2me" title="Feed2me">Feed2me</a>, a little spare-time project I&#8217;ve been working on recently.</p>
<p>Feed2me monitors your favourite RSS/Atom feeds and sends you an email when new entries are posted. It runs on <a href="https://developers.google.com/appengine/" title="Google App Engine">Google App Engine</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Installing Debian 7.1 &#8220;Wheezy&#8221;</title>
		<link>http://www.17od.com/2013/09/24/installing-debian-7-1-wheezy/</link>
		<comments>http://www.17od.com/2013/09/24/installing-debian-7-1-wheezy/#comments</comments>
		<pubDate>Tue, 24 Sep 2013 19:27:33 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[gthumb]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[radeon]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=744</guid>
		<description><![CDATA[Every time I install Linux, no matter what the distribution, I have the same problems; configuring video and audio. When I installed Debian 7.1 recently I documented the steps I took. Hopefully you&#8217;ll find something of use here. My Hardware &#8230; <a href="http://www.17od.com/2013/09/24/installing-debian-7-1-wheezy/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Every time I install Linux, no matter what the distribution, I have the same problems; configuring video and audio. When I installed Debian 7.1 recently I documented the steps I took. Hopefully you&#8217;ll find something of use here.</p>
<h2>My Hardware</h2>
<p><strong>Video</strong>: Advanced Micro Devices [AMD] nee ATI RV710 [Radeon HD 4350]<br />
<strong>Sound</strong>: Advanced Micro Devices [AMD] nee ATI RV710/730 HDMI Audio [Radeon HD 4000 series]<br />
<strong>Monitor</strong>: Dell SP2208WFP (with built in webcam)<br />
<strong>WebCam</strong>: OmniVision Technologies, Inc. Monitor Webcam</p>
<p>Video and sound devices can be determined using <em>lspci</em>. The Webcam is a USB device so it can be determined using <em>lsusb</em>.</p>
<h2>Video</h2>
<p>For regular use the <a href="https://wiki.debian.org/AtiHowTo">opensource Radeon display driver</a> is considered adequate. If you&#8217;re a gamer or just want to squeeze every bit of performance out of your card then you might consider the <a href="https://wiki.debian.org/ATIProprietary">AMD proprietary display driver</a>. For my needs the opensource driver is fine.</p>
<p>On the first boot GNOME 3 failed to load. The installer recognized my video card and installed the correct package, <a href="http://packages.debian.org/xserver-xorg-video-radeon">xserver-xorg-video-radeon</a>, but as documented <a href="https://wiki.debian.org/AtiHowTo#Installing_proprietary_firmware">on the wiki </a>my card requires proprietary firmware. This firmware is available in <strong>non-free</strong>. The steps to install it are,</p>
<ol>
<li>Open up <strong>Synaptic Package Manager</strong> and select <strong>Settings</strong>, <strong>Repositories</strong> from the menu</li>
<li>Tick the checkbox next to <strong>Non-DFSG-compatible Software (non-free)</strong></li>
<li>Click <strong>Close</strong> and then the <strong>Reload</strong> toolbar button</li>
<li>Search for and install <strong>firmware-linux-nonfree</strong></li>
<li>Reboot</li>
</ol>
<p>GNOME 3 should start successfully after the reboot.</p>
<h2>Audio</h2>
<p>When I didn&#8217;t hear any sound I thought I was going to be in for a world of pain with sound drivers, ALSA and PulseAudio. Luckily all I needed to do was select the right output device. My system has two sound devices, an onboard Intel device and the sound device on the AMD video card. My monitor is connected by HDMI. I have a soundbar on my monitor drawing it&#8217;s signal from the HDMI cable. All I needed to do was,</p>
<ol>
<li>Open up the <strong>System Settings</strong></li>
<li>Click the <strong>Sound</strong> icon</li>
<li>In the <strong>Output</strong> tab select the HDMI audio device, i.e. <strong>RV710/730 HDMI Audio [Radeon HD 4000 series] Digital Stereo (HDMI)</strong></li>
</ol>
<p><strong>Update (Aug-2014):</strong> HDMI audio is disabled by default in the kernel/audio driver. To enable it,</p>
<ol>
<li>Edit <strong>/etc/default/grub</strong> and append <strong>&#8220;radeon.audio=1&#8221;</strong> to the <strong>GRUB_CMDLINE_LINUX_DEFAULT</strong> variable.</li>
<li>Open a terminal execute <strong>sudo update-grub</strong></li>
<li>Reboot</li>
</ol>
<p>Source: <a href="http://askubuntu.com/a/68396" title="No sound on HDMI with Radeon driver">No sound on HDMI with Radeon driver</a></p>
<h2>Webcam</h2>
<p>My monitor has a built in Webcam. It&#8217;s an <strong>OmniVision Technologies, Inc. Monitor Webcam</strong>. I managed to get it working but it&#8217;s a bit hit and miss. When then uvcvideo kernel module is loaded it should create the device <em>/dev/video0</em>. Sometimes it does, sometimes it doesn&#8217;t. To get it to work is a matter of removing the module and reloading. After two or three attempts it usually works. Not very satisfying but I don&#8217;t use it very often so I&#8217;m not that bothered.</p>
<pre>
$ sudo modprobe -r uvcvideo     # unload the module
$ sudo modprobe uvcvideo        # load the module
</pre>
<p>Once the module loads successfully and creates the <em>/dev/video0</em> device you can use the <strong>Cheese</strong> application to test it.</p>
<h2>Microphone</h2>
<p>The mic didn&#8217;t appear to be working initially but as with audio out all I needed to do was select the right device and turn up the volume. I use the mic on my monitor (attached to the webcam).</p>
<ol>
<li>Open up the <strong>System Settings</strong></li>
<li>Click the <strong>Sound</strong> icon</li>
<li>Select the <strong>Input</strong> tab</li>
<li>Select the <strong>Monitor Webcam Analog Stero</strong> device</li>
<li>Turn the volume up to 100%</li>
</ol>
<p>After getting the hardware working these are the applications I installed.</p>
<h2>Flash Player</h2>
<p>The Flash Player package is avaiable from <strong>contrib</strong>.</p>
<ol>
<li>Open up <strong>Synaptic Package Manager</strong> and select <strong>Settings</strong>, <strong>Repositories</strong> from the menu</li>
<li>Tick the checkbox next to <strong>DFSG-compatible Software with Non-Free Dependencies (contrib)</strong></li>
<li>Click <strong>Close</strong> and then the <strong>Reload</strong> toolbar button</li>
<li>Search for and install <strong>flashplugin-nonfree</strong></li>
<li>Restart your browser if you</li>
</ol>
<p>Reference: <a href="https://wiki.debian.org/FlashPlayer">FlashPlayer</a> on the Debian Wiki</p>
<h2>Java Browser Plugin</h2>
<p>Simply install the package <strong>icedtea-6-plugin</strong>.</p>
<h2>gThumb</h2>
<p>gThumb is a photo manager. I prefer it over the default, Shotwell, because it feels quicker and more lightweight. I already organise my photos in a year, month, day folder structure so I have no need for anything fancy.</p>
<p>While gThumb itself is very easy to install (the <strong>gthumb</strong> package) it was failing to properly list all the photos and videos in a directory containing one or more videos. The problem was it couldn&#8217;t find the image it uses to surround videos (to give the reel effect). The fix is simple,</p>
<pre>
$ sudo ln -s /usr/share/gthumb/ui/filmholes.png /usr/share/filmholes.png
</pre>
<p>Reference: <a href="https://bugzilla.redhat.com/show_bug.cgi?id=842183">Redhat Bug 842183 &#8211; Gthumb breaks file list on movies</a></p>
<h2>Android Tools</h2>
<p>The Android Tools are used when developing Android applications. After installing the Android SDK I found adb wouldn&#8217;t work. When I ran it it gave a &#8220;file not found&#8221;. The problem is down to missing shared libraries. Here are the steps I took to fix it,</p>
<pre>
$ sudo dpkg --add-architecture i386
$ sudo aptitude update
$ sudo aptitude install libstdc++6:i386 libgcc1:i386 zlib1g:i386 libncurses5:i386
</pre>
<p>Reference: <a href="http://astroelec.blogspot.ie/2013/05/installing-android-sdk-tools-on-debian.html">Installing Android SDK tools on Debian Wheezy</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.17od.com/2013/09/24/installing-debian-7-1-wheezy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IFTTT &#8211; An Alternative to Feed Aggregators</title>
		<link>http://www.17od.com/2013/08/28/ifttt-an-alternative-to-feed-aggregators/</link>
		<pubDate>Wed, 28 Aug 2013 19:06:36 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[ifttt]]></category>
		<category><![CDATA[rss]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=726</guid>
		<description><![CDATA[Since Google Reader was retired I&#8217;ve been on the lookout for something a bit different. I tried out a few services but none of them really fit in with my way of doing things. When I thought about it all &#8230; <a href="http://www.17od.com/2013/08/28/ifttt-an-alternative-to-feed-aggregators/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Since <a href="http://googlereader.blogspot.ca/2013/03/powering-down-google-reader.html">Google Reader was retired</a> I&#8217;ve been on the lookout for something a bit different. I tried out a few services but none of them really fit in with my way of doing things. When I thought about it all I really wanted was a service that would send me an email when a new entry was posted to a blog I liked. Luckily that&#8217;s exactly the kind of thing <a href="http://www.ifttt.com/">IFTTT</a> does.</p>
<p>IFTTT is a web service that allows you to create little &#8220;programs&#8221;. These programs, or recipes as they&#8217;re called, carry out an action following some trigger event. Each recipe has the same structure; &#8220;if this happens then do that&#8221;. The &#8220;this&#8221; piece is called the trigger. The &#8220;that&#8221; piece is called the action.</p>
<p>Example triggers,</p>
<ul>
<li>I tweet a message</li>
<li>I update my Facebook status</li>
<li>I upload a photo to Instagram</li>
<li>A new entry is posted to a blog</li>
</ul>
<p>Example actions,</p>
<ul>
<li>Send me an SMS</li>
<li>Upload a photo to Facebook</li>
<li>Add an event to my Google Calendar</li>
<li>Send me an email</li>
</ul>
<p>See <a href="https://ifttt.com/wtf">About IFTTT</a> for a more comprehensive description.</p>
<p>Actions and triggers are organized into <a href="https://ifttt.com/channels">channels</a>, e.g. Facebook, Dropbox, Email, Feed (i.e. blog feed), etc.</p>
<p>Using the &#8220;New feed item&#8221; trigger in the Feed channel and the &#8220;Send me an email&#8221; action in the Email channel I put together a recipe for each blog I wanted to subscribe to. Here&#8217;s what my XKCD recipe looks like,</p>
<p><a href="http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_recipe.png"><img src="http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_recipe-271x300.png" alt="XKCD Recipe" width="271" height="300" class="shutterset aligncenter size-medium wp-image-727" srcset="http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_recipe-271x300.png 271w, http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_recipe-624x688.png 624w, http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_recipe.png 644w" sizes="(max-width: 271px) 100vw, 271px" /></a></p>
<p>The email subject has the blog name and entry title. For the body I chose to include a link to the entry rather than the full text. Here&#8217;s what an email from IFTTT looks like,</p>
<p><a href="http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_monster.png"><img src="http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_monster-300x111.png" alt="XKD Monster" width="300" height="111" class="shutterset aligncenter size-medium wp-image-728" srcset="http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_monster-300x111.png 300w, http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_monster-624x231.png 624w, http://www.17od.com/wordpress/wp-content/uploads/2013/08/xkcd_monster.png 716w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>I&#8217;ve subscribed to number of blogs this way. What I really like is getting email notifications pushed to me rather than having to use a blog aggregation tool. I use email as a sort of TODO list. This way I can treat new blog posts as something I need to do. Once I have the email I can come back to it whenever I want.</p>
<p>As good as IFTTT is there are some rough edges for my particular use case. I wouldn&#8217;t say they&#8217;re problems though because IFTTT is meant to be a general service.</p>
<ol>
<li>If I want to subscribe to a new blog it&#8217;s a bit of a nuisance having to create a whole new recipe from scratch. It would be great if I could create a new recipe based on another one. That way all I&#8217;d need to change is the recipe&#8217;s name, the blog feed URL and the mail subject (which includes the blog title). The positive side of this is that it stops me subscribing to blogs willy-nilly. I prefer a few quality subscriptions.</li>
<li>I&#8217;d like to be able to export my recipes. Why? I think it&#8217;s the programmer in me. Now I have all these recipes I feel like they should be under version control.</li>
<li>An IFTTT API would be great. If there was an API to create a recipe I could create a browser extension to automatically create a &#8220;Subscribe to RSS&#8221; recipe while on a blog.</li>
</ol>
<p>So that&#8217;s my experience. It works for me.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Using Lego Mindstorms on Ubuntu</title>
		<link>http://www.17od.com/2013/01/13/using-lego-mindstorms-on-ubuntu/</link>
		<pubDate>Sun, 13 Jan 2013 20:57:06 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[lego]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=705</guid>
		<description><![CDATA[When I was growing up I loved playing with Lego, mechanical construction sets, chemistry sets (with proper dangerous chemicals kids), wood, metal, basically anything where I could build something with my hands. I even remember going though a phase of &#8230; <a href="http://www.17od.com/2013/01/13/using-lego-mindstorms-on-ubuntu/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>When I was growing up I loved playing with Lego, mechanical construction sets, chemistry sets (with proper dangerous chemicals kids), wood, metal, basically anything where I could build something with my hands. I even remember going though a phase of building lamp shades with ice-cream sticks. I don&#8217;t know how many dog houses and go-karts my brothers and I built. Thankfully I grew up in the <a href="http://en.wikipedia.org/wiki/County_Cavan">Irish countryside</a> where we had lots of space. It also helped that my father was a builder so there was always lots of material and tools about the house he was happy to let us borrow (we didn&#8217;t like to bother him by asking him for any of it of course :))</p>
<p>I think it was all this building stuff that led me into a career in programming. Weather you&#8217;re using your mind or your hands it&#8217;s the process of making something out of nothing I really love.</p>
<p>I miss using my hands and so after hearing recently about Lego&#8217;s new <a href="http://techcrunch.com/2013/01/06/lego-mindstorms-ev3-the-better-faster-stronger-generation-of-robotic-programming/">EV3 platform</a> I pulled out my old <a href="http://en.wikipedia.org/wiki/Lego_Mindstorms#Robotics_Invention_System">Mindstorms Robotics Invention System 2.0</a>. This is pretty old set but it&#8217;s still perfectly useabable. It comes with two motors, two touch sensors, a light sensor, an RCX (the computer) and more bits of Lego than you can shake a stick at.</p>
<p>I run Ubuntu so the Windows based program that came in the kit would have to stay there (besides, the cover says it only supports Windows 98/ME so what are the chances it&#8217;ll work on Windows 7).</p>
<p>What I needed was to do was get the infrared tower used to transmit programs to the RCX working. I wasn&#8217;t all that hopeful but after plugging it in I was more than surprised to see a new device appear, <strong>/dev/usb/legousbtower0</strong>. Apparently the <a href="http://legousb.sourceforge.net/">Lego USB tower kernel module</a> has been part of base Linux for some time now. How cool is that.</p>
<p>Now I needed a programming language. A quick google and I came across <a href="http://bricxcc.sourceforge.net/nqc/">Not Quite C</a>. It has a C-like syntax but given the restrictions of the RCX it&#8217;s pretty straight forward. What&#8217;s even better is it&#8217;s available from the Ubuntu repositories.</p>
<pre crayon="false">$ sudo apt-get install nqc</pre>
<p>The next step was the trickiest, getting nqc to recognize the device. The first step was to give my user access to the <strong>/dev/usb/legousbtower0</strong> device. This can be done with the command <code>sudo chmod 666 /dev/usb/legousbtower0</code>. For a more permanent solution create the file <strong>/etc/udev/rules.d/90-legotower.rules</strong> with the following contents,</p>
<pre crayon="false">
ATTRS{idVendor}=="0694",ATTRS{idProduct}=="0001",MODE="0666",GROUP="&lt;group&gt;"
</pre>
<p>You can use any group you&#8217;re a member of in place of &lt;group&gt;. You can find a list of the groups you&#8217;re a member of using &#8216;<code>id -a</code>&#8216;. I used the group &#8220;adrian&#8221;. On a lot of systems there&#8217;ll be a group with the same name as your used id. This is fine so long as you&#8217;re the only one who&#8217;ll need access to the device. Otherwise you&#8217;ll need to find a common group or perhaps create a new one. By the way, the vendor and product ids in the udev rules file came from running <strong>lsusb</strong>.</p>
<p>The first time I tried to transfer a program to the RCX I got an error saying there was no firmware on the device. Apparently it only lasts as long as the batteries are powered. The nqc command can be used to install the firmware so all I needed to do was locate the firmware file. A few sites talk about the file <strong>/firm/firm0309.lgo</strong> on the system CD. My CD has no such file. I knew the firmware had to be on there somewhere though. Eventually I found it in the file <strong>data2.cab</strong>. This is an InstallShield archive. To extract the file install <strong>unshield</strong> and then expand the CAB file.</p>
<pre crayon="false">
$ sudo apt-get install unshield
$ unshield -d /tmp/lego x &lt;path to CD&gt;/RIS2/data1.cab
</pre>
<p>The firmware file will be located at <strong>/tmp/lego/Script/Firmware/firm0328.lgo</strong>.</p>
<p>To install the firmware run,</p>
<pre crayon="false">
$ nqc -Susb -firmware /tmp/lego/Script/Firmware/firm0328.lgo
</pre>
<p>Needless to say the USB tower has to be connected and pointing towards your powered on RCX. The transfer takes a few minutes to complete.</p>
<p>Finally, here&#8217;s how to transfer a simple program (source file prog1.nqc) to the RCX and have it run automatically,</p>
<pre crayon="false">
$ nqc -Susb -d prog1.nqc -run
</pre>
<p>Now that everything is up and running I can get on with building something.</p>
<p>Links</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Not_Quite_C">Not Quite C &#8211; Wikipedia</a></li>
<li><a href="http://bricxcc.sourceforge.net/nqc/">Not Quite C</a></li>
<li><a href="A tutorial http://www.staff.science.uu.nl/~overm101/lego/tutorial.pdf">Programming Lego Robots using NQC</a></li>
<li><a href="http://www.philohome.com/sdk25/sdk25.htm">MINDSTORMS SDK2.5</a> An archive of RCX tools no longer available on the Lego site. Not relevant on Ubuntu but may be of use to someone.</li>
</ul>
]]></content:encoded>
			</item>
		<item>
		<title>Ten Useful Openstack Swift Features</title>
		<link>http://www.17od.com/2012/12/19/ten-useful-openstack-swift-features/</link>
		<comments>http://www.17od.com/2012/12/19/ten-useful-openstack-swift-features/#comments</comments>
		<pubDate>Wed, 19 Dec 2012 20:33:07 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[openstack]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=607</guid>
		<description><![CDATA[CORS support For security reasons Javascript running in a browser is not allowed to make requests to domains other than the one from where it came from. This is referred to as the Same Origin Policy. CORS is specification allowing &#8230; <a href="http://www.17od.com/2012/12/19/ten-useful-openstack-swift-features/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h2>CORS support</h2>
<p>For security reasons Javascript running in a browser is not allowed to make requests to domains other than the one from where it came from. This is referred to as the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">Same Origin Policy<a/>. <a href="http://en.wikipedia.org/wiki/Cross-origin_resource_sharing">CORS</a> is specification allowing browsers and application servers work out an agreement whereby these types of requests are allowed.</p>
<p>Swift 1.7.5 introduced <a href="http://docs.openstack.org/developer/swift/misc.html#cors-headers">CORS support</a>. This means a Javascript application running in a browser and hosted outside of a Swift cluster can still query that cluster&#8217;s API. I expect to see lots of Swift based applications over the coming months thanks to this great new feature.</p>
<h2>The ETag</h2>
<p>Every object written to a Swift cluster has an <a href="http://en.wikipedia.org/wiki/HTTP_ETag">ETag</a> associated with it. The value of this ETag is the MD5 digest of the file&#8217;s contents. What makes this useful is that you can use it to make a conditional request for the object using the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24">If-Match</a>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26">If-None-Match</a> headers.</p>
<p>For example, lets say your Swift cluster contains the object &#8220;movie1.mp4&#8221;. You already have a version of the file locally but you&#8217;re not sure if it&#8217;s exactly the same. You don&#8217;t want to have to download it unnecessarily because it would take too long and/or might incur bandwidth charges. What you can do is invoke a conditional download request, i.e.</p>
<pre class="lang:sh decode:true">$ md5sum movie1.mp4
d41d8cd98f00b204e9800998ecf8427e  movie1.mp4

$ curl -i -H 'X-Auth-Token: xxx' -H 'If-None-Match: d41d8cd98f00b204e9800998ecf8427e' http://swift.17od.com/movies/movie1.mp4
HTTP/1.1 304 Not Modified
...</pre>
<p>The 304 response code tells us that our local version is the same as the remote version. If it wasn&#8217;t the same it would be downloaded.</p>
<h2>Object Versioning</h2>
<p>With object versioning, each PUT request to an object will result in the existing object being archived to a special &#8220;versions&#8221; container.</p>
<p>Versioning is controlled at the container level by setting the header &#8220;X-Versions-Location&#8221; to the name of the container where you want to archive object versions.</p>
<p>For more information see <a href="http://docs.openstack.org/developer/swift/overview_object_versioning.html">Object Versioning</a> in the developer documentation. </p>
<h2>Renaming or Moving an Object</h2>
<p>Renaming or moving objects isn&#8217;t supported in the classic sense. However the same result can be achieved by downloading the existing object and re-uploading it to the new container and/or with a new name. Of course if the object is large this can be a time consuming operation. Luckily Swift supports server side copies. What this means is this object is copied from it&#8217;s source to destination all within the confines of the Swift cluster.</p>
<p>Either PUT or COPY can be used to perform a server side copy. Neither has an advantage over the other.</p>
<p>For example, given the container and object &#8220;photos/sunset.jpg&#8221;, here&#8217;s how to move it to &#8220;holiday-pics/sunset_glow.jpg&#8221;.</p>
<pre class="lang:sh decode:true">
$ curl -X PUT -H 'X-Auth-Token: xxx' -H 'X-Copy-From: /photos/sunset.jpg' http://swift.17od.com/holiday-pics/sunset_glow.jpg
</pre>
<p>See <a href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/copy-object.html">Copy Object</a> for more details.</p>
<h2>Expiring Objects</h2>
<p>Objects can be given an expiry time. When that time is reached Swift will automatically delete the object. Object&#8217;s are given an expiry time by setting either the <b>X-Delete-At</b> or <b>X-Delete-After</b> headers.</p>
<p>The value given to X-Delete-At is a <a href="http://en.wikipedia.org/wiki/Unix_time">Unix Epoch timestamp</a>. There are many ways of converting a time to an epoch integer. For example on UNIX you can to,</p>
<pre class="lang:sh decode:true">
$ date +%s
1355945201
</pre>
<p>The <a href="http://www.epochconverter.com/">epoch converter</a> website allows you to convert any time to an epoch and vice-versa.</p>
<p>X-Delete-After is a convenience header allowing you to give the number of seconds from now when you want the object deleted. Swift will use this value to calculate an epoch time this number of seconds into the future and set an X-Delete-At header on the object.</p>
<pre class="lang:sh decode:true">
# delete the object on Sat, 19 Dec 2015 19:18:52 GMT
$ curl -X POST -H 'X-Auth-Token: xxx' -H 'X-Delete-On: 1450552732' http://swift.17od.com/holiday-pics/sunset_glow.jpg
</pre>
<pre class="lang:sh decode:true">
# delete the object 24 hours from now, 24*60*60
$ curl -X POST -H 'X-Auth-Token: xxx' -H 'X-Delete-After: 86400' http://swift.17od.com/holiday-pics/sunset_glow.jpg
</pre>
<p>See <a href="http://docs.openstack.org/developer/swift/overview_expiring_objects.html">Expiring Object Support</a> in the developer documentation for more information.</p>
<h2>Segmented Objects</h2>
<p>Swift has an object size limit of 5Gb. Larger objects must be split up on the client side and the segments uploaded individually. A manifest object is then used to create a logical object built up from the segments.</p>
<p>It&#8217;s not just large objects that can be segmented. Any sized object can be broken up. Having said that I can&#8217;t think of a good reason why you&#8217;d want to do this?</p>
<p>On UNIX the <code>split</code> command can be used to split an object up into segments. There&#8217;s two ways of using split, either give it the number of segments or the size of the segments you want to split the object up into.</p>
<pre class="lang:sh decode:true">
# split an object up into 5 segments
$ split -n 5 at_the_beach.mp4 at_the_beach.mp4-

# split an object up where each segment is at most 5GB
$ split -b 5G at_the_beach.mp4 at_the_beach.mp4-
</pre>
<p>In each case the result will be a number of files called <code>at_the_beach.mp4-xx</code> where xx is an alphabetically ordered sequence of characters, e.g. aa, ab, ac and so on. This ordering is important because when Swift rebuilds the object it sorts the segments by name before concatenating them. Each of these segments should be uploaded into the same container.</p>
<p>The manifest object is an object with no content. Instead it has the header <code>X-Object-Manifest</code>. The value of this header is the container name and common prefix of the segments making up the object. Assuming the segments were uploaded into a container called &#8216;holiday-pics&#8217; and the prefix was &#8216;at_the_beach.mp4-&#8216; the header value would be &#8216;holiday-pics/at_the_beach.mp4-&#8216;.</p>
<pre class="lang:sh decode:true">
$ curl -X PUT -H 'X-Auth-Token: xxx' -H 'X-Object-Manifest: holiday-pics/at_the_beach.mp4-' http://swift.17od.com/holiday-pics/at_the_beach.mp4
</pre>
<p>A GET for the manifest object will return the reassembled source object. Swift will stream each segment in sequence so from the client side it will appear as one continuous object.</p>
<p>See <a href="http://docs.openstack.org/developer/swift/overview_large_objects.html">Large Object Support</a> in the developer documentation for more information.</p>
<h2>Metadata</h2>
<p>Accounts, Containers and Objects can all have custom metadata headers associated with them. These headers are simple name/value pairs. Custom headers are distinguished from system headers with a prefix, X-Account-Meta, X-Container-Meta or X-Object-Meta.</p>
<p>Headers can be set on an existing account, container or object using the POST method. Alternatively the headers can be set when the container or object is being created using PUT.</p>
<pre class="lang:sh decode:true">
# Set a header on an existing object
$ curl -X POST -H 'X-Auth-Token: xxx' -H 'X-Object-Meta-Location: Dublin' http://swift.17od.com/holiday-pics/at_the_beach.mp4

# Set a header on a container when creating it
$ curl -X PUT -H 'X-Auth-Token: xxx' -H 'X-Container-Meta-Year: 2012' http://swift.17od.com/holiday-pics/
</pre>
<p>Metadata can be retrieved using the HEAD method.</p>
<pre class="lang:sh decode:true">
$ curl -i -X HEAD -H 'X-Auth-Token: xxx' http://swift.17od.com/holiday-pics/
HTTP/1.1 204 No Content
Content-Length: 0
X-Container-Object-Count: 3
Accept-Ranges: bytes
X-Timestamp: 1355861803.81992
X-Container-Bytes-Used: 2
X-Container-Meta-Year: 2012
Content-Type: text/plain; charset=utf-8
Date: Wed, 19 Dec 2012 20:07:03 GMT
</pre>
<h2>Permissions</h2>
<p>Permissions in Swift are controlled at the container level. Only users classified as administrators can create containers. By default regular users can&#8217;t create or access containers. </p>
<p>Users can be given read or write permissions for all the objects in a container using the X-Container-Read and X-Container-Write headers.</p>
<pre class="lang:sh decode:true">
# Give bob and alice read access to the holiday-pics container
$ curl -X POST -H 'X-Auth-Token: xxx' -H 'X-Container-Read: bob, alice' http://swift.17od.com/holiday-pics/

# Give bob write access to the holiday-pics container
$ curl -X POST -H 'X-Auth-Token: xxx' -H 'X-Container-Write: bob' http://swift.17od.com/holiday-pics/
</pre>
<p>For more information see the <a href="http://docs.openstack.org/developer/swift/misc.html#acls">ACLs</a> section of the developer docs.</p>
<h2>Pseudo-Hierarchical Directories</h2>
<p>While containers can be compared with regular filesystem directories, it&#8217;s not possible to nest them. A container with thousands of objects can become extremely difficult to navigate and manage. With that in mind Swift supports a feature called pseudo-hierarchical directories. These are directory structures derived from the names of objects themselves. For example, lets say we have a container with the following six objects,</p>
<p>photos/2010/001.jpg<br />
photos/2011/001.jpg<br />
photos/2011/002.jpg<br />
photos/2012/001.jpg<br />
photos/2012/002.jpg<br />
photos/2012/003.jpg</p>
<p>By using a delimiter character Swift can be asked to list the objects as if they were in a directory structure similar to,</p>
<pre class="show-plain-default:true nums:false lang:default decode:true " >
/photos/
|-- 2010
|   `-- 001.jpg
|-- 2011
|   |-- 001.jpg
|   `-- 002.jpg
`-- 2012
    |-- 001.jpg
    |-- 002.jpg
    `-- 003.jpg
</pre>
<p>For example,</p>
<pre class="lang:sh decode:true">
$ curl -X GET -H 'X-Auth-Token: xxx' http://swift.17od.com/adrian/?delimiter=/
photos/

$ curl -X GET -H 'X-Auth-Token: xxx' "http://swift.17od.com/adrian/?delimiter=/&prefix=photos/"
photos/2010/
photos/2011/
photos/2012/

$ curl -X GET -H 'X-Auth-Token: xxx' "http://swift.17od.com/adrian/?delimiter=/&prefix=photos/2012/"
photos/2012/001.jpg
photos/2012/002.jpg
photos/2012/003.jpg
</pre>
<p>For more information see <a href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/pseudo-hierarchical-folders-directories.html">Pseudo-Hierarchical Folders/Directories</a> in the Developer Guide.</p>
<h2>Swift All in One</h2>
<p>Like anything, the best way to learn more about Swift it to play around with it. Luckily that&#8217;s relatively easy thanks to <a href="http://docs.openstack.org/developer/swift/development_saio.html">Swift All in One</a>, a set of instructions describing how to setup a fully functional Swift cluster on a single machine (ideally a VM).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.17od.com/2012/12/19/ten-useful-openstack-swift-features/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Testing Android Activity &#038; Process Lifecycles</title>
		<link>http://www.17od.com/2011/11/20/testing-android-activity-process-lifecycles/</link>
		<pubDate>Sun, 20 Nov 2011 20:04:50 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[android]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=473</guid>
		<description><![CDATA[Developing robust Android applications is challenging. At any moment your application can be interrupted, sent the background or just simply terminated. There are a few hooks to help you prepare for these scenarios but it&#8217;s such a dynamic environment it &#8230; <a href="http://www.17od.com/2011/11/20/testing-android-activity-process-lifecycles/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Developing robust Android applications is challenging. At any moment your application can be interrupted, sent the background or just simply terminated. There are <a href="http://developer.android.com/guide/topics/fundamentals/activities.html#ImplementingLifecycleCallbacks">a few hooks</a> to help you prepare for these scenarios but it&#8217;s such a dynamic environment it can be hard to anticipate how your application will behave.</p>
<p>Take the <a href="http://developer.android.com/guide/topics/fundamentals/activities.html#Lifecycle">activity lifecycle</a> for example. Under normal circumstances activities are only destroyed when their <em>finish()</em> method is called or the system needs to free up some memory. From a testing perspective this isn&#8217;t very deterministic so testing what happens when activities are destroyed is either forgotten about or not given the attention it deserves.</p>
<p>Luckily there are tools to help in these scenarios. The <a href="http://developer.android.com/guide/developing/debugging/debugging-devtools.html">Dev Tools App</a> is particularly useful. It&#8217;s automatically installed with every virtual device created using the Android Virtual Device Manager in Eclipse.</p>
<h2>Testing Activity Destruction</h2>
<p>To test what happens to your app when activities are destroyed tick the <em>Immediately destroy activities</em> checkbox under <em>Development Settings</em> in <em>Dev Tools</em>. This instructs Android to immediately destroy activities that are no longer visible. Under normal conditions you might never get to this test scenario if you don&#8217;t explicitly call <em>finish()</em> on your activities. It&#8217;s amazing the subtle bugs this can throw up.</p>
<h2>Testing Process Termination</h2>
<p>Another very useful test is to see what happens when your application&#8217;s process is terminated. When I stated out with <a href="https://market.android.com/details?id=com.u17od.upm">UPM</a> I received quite a number of crash reports that initially baffled me. The stack traces suggested situations that I just couldn&#8217;t recreate. It wasn&#8217;t until I started thinking about the impact of process termination that I found the root of the problems.</p>
<p>When a terminated application is restarted Android will try and return the user to whatever activity was previously in the foreground. This can cause problems if the activity assumes too much about the application&#8217;s state, e.g. what static variables are initialized. Restarting the application means there&#8217;s a new process so the static state of the previous instance is gone. Here&#8217;s how I test this scenario.</p>
<p>First I start the application in an emulator as normal. Once I&#8217;ve made it to the activity under test I hit the Home button to send the application into the background. Now I need to kill the application&#8217;s process. There&#8217;s a few ways to do this. My favourite is to use <a href="http://developer.android.com/guide/developing/tools/adb.html">adb</a>. adb is located in the Android SDK platform-tools directory. Running </p>
<pre>$ adb shell</pre>
<p> starts a shell on the emulator. From there I use </p>
<pre>$ ps</pre>
<p> to find the application&#8217;s process and </p>
<pre>$ kill -9 &lt;pid&gt;</pre>
<p> to kill the process. Once I&#8217;ve killed the process I go back to the emulator and hit the application&#8217;s icon to restart it. Android will try to resume the activity that was previously in the foreground. Ideally there should be no problems but if there are they&#8217;ll usually present themselves as a NullPointerException with a &#8220;Force Close&#8221; dialog for the user.</p>
<p>Android can be a difficult, confusing platform to work with. This is particularly true if you&#8217;re coming from a regular desktop application environment. There&#8217;s a paradigm shift in thinking required to fully appreciate the transient nature of the Android environment. Thankfully, once you&#8217;ve made that leap things do get easier. The most useful resources I&#8217;ve found are the <a href="http://developer.android.com/guide/index.html">Android Developer&#8217;s Guide</a> and <a href="http://stackoverflow.com/questions/tagged/android">Stackoverflow</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Searching the PRTB Database</title>
		<link>http://www.17od.com/2011/05/14/searching-the-prtb-database/</link>
		<pubDate>Sat, 14 May 2011 14:59:34 +0000</pubDate>
		<dc:creator><![CDATA[Adrian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[prtb]]></category>

		<guid isPermaLink="false">http://www.17od.com/?p=444</guid>
		<description><![CDATA[The PRTB publish a list of all registered rental properties in Ireland on their website. The data is split up into 47 separate spreadsheets (xls), one for each county and Dublin postcode. There&#8217;s a lot of interesting information in there &#8230; <a href="http://www.17od.com/2011/05/14/searching-the-prtb-database/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<style type="text/css">
  table td.number {
    text-align: right;
  }
</style>
<p>The <a href="https://www.prtb.ie/">PRTB</a> publish a list of <a href="https://www.prtb.ie/public_registrations.aspx">all registered rental properties in Ireland</a> on their website. The data is split up into 47 separate spreadsheets (xls), one for each county and Dublin postcode. There&#8217;s a lot of interesting information in there but it&#8217;s very difficult to get at it when it&#8217;s in so many files. For this reason I&#8217;ve loaded all the information into a database.</p>
<p>Before looking at the data it&#8217;s worth bearing a few things in mind,</p>
<ul>
<li>the data is effective 1-Apr-2011</li>
<li>there are a lot of properties included in &#8220;County Dublin&#8221; that are really part of an area code. this has the effect of bumping up the number of properties in &#8220;County Dublin&#8221;</li>
<li>some properties appear to have their floorspace given in square meters while others have it in square feet. this makes it difficult to do a consistent  analysis of the full dataset</li>
<li>there seems to be a few properties with duplicate entries</li>
</ul>
<p>I&#8217;ve included some high level numbers below. If you&#8217;d like to have a look at the data yourself I&#8217;ve <a href="http://www.17od.com/prtb/">published it in searchable form here</a>. The code for this application is <a href="https://github.com/adrian/search-prtb">available on my GitHub page</a>.</p>
<p><strong>Total number of properties:</strong> 221,315</p>
<p><strong>Number of properties per county:</strong></p>
<table>
<tr>
<td>Dublin</td>
<td class="number">67,828</td>
</tr>
<tr>
<td>Cork</td>
<td class="number">27,631</td>
</tr>
<tr>
<td>Galway</td>
<td class="number">15,626</td>
</tr>
<tr>
<td>Kildare</td>
<td class="number">8,807</td>
</tr>
<tr>
<td>Waterford</td>
<td class="number">6,079</td>
</tr>
<tr>
<td>Kerry</td>
<td class="number">5,684</td>
</tr>
<tr>
<td>Wexford</td>
<td class="number">5,571</td>
</tr>
<tr>
<td>Meath</td>
<td class="number">5,441</td>
</tr>
<tr>
<td>Wicklow</td>
<td class="number">5,372</td>
</tr>
<tr>
<td>Tipperary</td>
<td class="number">5,250</td>
</tr>
<tr>
<td>Sligo</td>
<td class="number">4,545</td>
</tr>
<tr>
<td>Westmeath</td>
<td class="number">4,520</td>
</tr>
<tr>
<td>Mayo</td>
<td class="number">4,269</td>
</tr>
<tr>
<td>Louth</td>
<td class="number">4,223</td>
</tr>
<tr>
<td>Clare</td>
<td class="number">3,888</td>
</tr>
<tr>
<td>Donegal</td>
<td class="number">3,566</td>
</tr>
<tr>
<td>Kilkenny</td>
<td class="number">3,134</td>
</tr>
<tr>
<td>Carlow</td>
<td class="number">2,806</td>
</tr>
<tr>
<td>Laois</td>
<td class="number">2,276</td>
</tr>
<tr>
<td>Offaly</td>
<td class="number">2,165</td>
</tr>
<tr>
<td>Longford</td>
<td class="number">1,947</td>
</tr>
<tr>
<td>Roscommon</td>
<td class="number">1,922</td>
</tr>
<tr>
<td>Cavan</td>
<td class="number">1,783</td>
</tr>
<tr>
<td>Limerick</td>
<td class="number">1,764</td>
</tr>
<tr>
<td>Leitrim</td>
<td class="number">1,185</td>
</tr>
<tr>
<td>Monaghan</td>
<td class="number">222</td>
</tr>
</table>
<p><strong>Number of properties per Dublin area code</strong>:</p>
<table>
<tr>
<td>Dublin County</td>
<td class="number">18,216</td>
</tr>
<tr>
<td>Dublin 8</td>
<td class="number">8,472</td>
</tr>
<tr>
<td>Dublin 15</td>
<td class="number">7,417</td>
</tr>
<tr>
<td>Dublin 1</td>
<td class="number">6,792</td>
</tr>
<tr>
<td>Dublin 4</td>
<td class="number">6,732</td>
</tr>
<tr>
<td>Dublin 7</td>
<td class="number">6,529</td>
</tr>
<tr>
<td>Dublin 9</td>
<td class="number">4,726</td>
</tr>
<tr>
<td>Dublin 24</td>
<td class="number">3,930</td>
</tr>
<tr>
<td>Dublin 2</td>
<td class="number">3,736</td>
</tr>
<tr>
<td>Dublin 3</td>
<td class="number">3,708</td>
</tr>
<tr>
<td>Dublin 18</td>
<td class="number">3,201</td>
</tr>
<tr>
<td>Dublin 14</td>
<td class="number">2,902</td>
</tr>
<tr>
<td>Dublin 6W</td>
<td class="number">2,599</td>
</tr>
<tr>
<td>Dublin 11</td>
<td class="number">2,595</td>
</tr>
<tr>
<td>Dublin 12</td>
<td class="number">2,098</td>
</tr>
<tr>
<td>Dublin 22</td>
<td class="number">1,960</td>
</tr>
<tr>
<td>Dublin 16</td>
<td class="number">1,555</td>
</tr>
<tr>
<td>Dublin 13</td>
<td class="number">1,496</td>
</tr>
<tr>
<td>Dublin 5</td>
<td class="number">1,485</td>
</tr>
<tr>
<td>Dublin 20</td>
<td class="number">586</td>
</tr>
<tr>
<td>Dublin 17</td>
<td class="number">542</td>
</tr>
<tr>
<td>Dublin 10</td>
<td class="number">362</td>
</tr>
</table>
]]></content:encoded>
			</item>
	</channel>
</rss>
