<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Confessions of a Guru</title>
	
	<link>http://www.guru.net.nz/blog</link>
	<description>Random stuff from a Dunedin (NZ) based web developer, beer drinker and dad</description>
	<pubDate>Mon, 01 Jun 2009 11:04:50 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7-hemorrhage</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ConfessionsOfAGuru" type="application/rss+xml" /><item><title>Snowed in [Flickr]</title><link>http://www.flickr.com/photos/gurubob/3630188461/</link><dc:creator>gurubobnz</dc:creator><pubDate>Mon, 15 Jun 2009 17:40:02 PDT</pubDate><guid isPermaLink="false">tag:flickr.com,2005:/photo/3630188461</guid><description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/gurubob/"&gt;gurubobnz&lt;/a&gt; posted a photo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/gurubob/3630188461/" title="Snowed in"&gt;&lt;img src="http://farm4.static.flickr.com/3365/3630188461_3b330c6ce6_m.jpg" width="240" height="180" alt="Snowed in" /&gt;&lt;/a&gt;&lt;/p&gt;

</description><enclosure url="http://farm4.static.flickr.com/3365/3630188461_c6eec69bb2_o.jpg" length="0" type="image/jpeg" /><dc:date.Taken>2009-06-16T09:13:01-08:00</dc:date.Taken></item><item><title>Ada at Brockville Park [Flickr]</title><link>http://www.flickr.com/photos/gurubob/3631002712/</link><dc:creator>gurubobnz</dc:creator><pubDate>Mon, 15 Jun 2009 17:39:44 PDT</pubDate><guid isPermaLink="false">tag:flickr.com,2005:/photo/3631002712</guid><description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/gurubob/"&gt;gurubobnz&lt;/a&gt; posted a photo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/gurubob/3631002712/" title="Ada at Brockville Park"&gt;&lt;img src="http://farm3.static.flickr.com/2428/3631002712_c9f98a21c4_m.jpg" width="240" height="180" alt="Ada at Brockville Park" /&gt;&lt;/a&gt;&lt;/p&gt;

</description><enclosure url="http://farm3.static.flickr.com/2428/3631002712_e7a1737f97_o.jpg" length="0" type="image/jpeg" /><dc:date.Taken>2009-06-16T09:44:53-08:00</dc:date.Taken></item><item><title>Snow seat at Brockville Park [Flickr]</title><link>http://www.flickr.com/photos/gurubob/3630186387/</link><dc:creator>gurubobnz</dc:creator><pubDate>Mon, 15 Jun 2009 17:39:18 PDT</pubDate><guid isPermaLink="false">tag:flickr.com,2005:/photo/3630186387</guid><description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/gurubob/"&gt;gurubobnz&lt;/a&gt; posted a photo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/gurubob/3630186387/" title="Snow seat at Brockville Park"&gt;&lt;img src="http://farm4.static.flickr.com/3545/3630186387_ce9cdbbaf0_m.jpg" width="240" height="180" alt="Snow seat at Brockville Park" /&gt;&lt;/a&gt;&lt;/p&gt;

</description><enclosure url="http://farm4.static.flickr.com/3545/3630186387_26b3a2d1a6_o.jpg" length="0" type="image/jpeg" /><dc:date.Taken>2009-06-16T09:47:19-08:00</dc:date.Taken></item><item><title>Brockville Rd looking towards Mt. Grant [Flickr]</title><link>http://www.flickr.com/photos/gurubob/3630185805/</link><dc:creator>gurubobnz</dc:creator><pubDate>Mon, 15 Jun 2009 17:39:05 PDT</pubDate><guid isPermaLink="false">tag:flickr.com,2005:/photo/3630185805</guid><description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/gurubob/"&gt;gurubobnz&lt;/a&gt; posted a photo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/gurubob/3630185805/" title="Brockville Rd looking towards Mt. Grant"&gt;&lt;img src="http://farm4.static.flickr.com/3597/3630185805_3d2fbb4ac9_m.jpg" width="240" height="180" alt="Brockville Rd looking towards Mt. Grant" /&gt;&lt;/a&gt;&lt;/p&gt;

</description><enclosure url="http://farm4.static.flickr.com/3597/3630185805_5b2d2bf7e5_o.jpg" length="0" type="image/jpeg" /><dc:date.Taken>2009-06-16T09:49:07-08:00</dc:date.Taken></item><item><title>Snowed In [Flickr]</title><link>http://www.flickr.com/photos/gurubob/3630185175/</link><dc:creator>gurubobnz</dc:creator><pubDate>Mon, 15 Jun 2009 17:38:52 PDT</pubDate><guid isPermaLink="false">tag:flickr.com,2005:/photo/3630185175</guid><description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/gurubob/"&gt;gurubobnz&lt;/a&gt; posted a photo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/gurubob/3630185175/" title="Snowed In"&gt;&lt;img src="http://farm4.static.flickr.com/3629/3630185175_060d2f47ba_m.jpg" width="240" height="180" alt="Snowed In" /&gt;&lt;/a&gt;&lt;/p&gt;

</description><enclosure url="http://farm4.static.flickr.com/3629/3630185175_f46dd7fd26_o.jpg" length="0" type="image/jpeg" /><dc:date.Taken>2009-06-16T09:13:53-08:00</dc:date.Taken></item><item>
		<title>Screen scraping with jQuery</title>
		<link>http://www.guru.net.nz/blog/2009/06/screen-scraping-with-jquery.html</link>
		<comments>http://www.guru.net.nz/blog/2009/06/screen-scraping-with-jquery.html#comments</comments>
		<pubDate>Mon, 01 Jun 2009 11:04:50 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=268</guid>
		<description><![CDATA[During the course of my job I often find myself faced with the task of migrating information from an existing website to our own content management system.  In the past my approach to this task has been to assess the source code of the existing site and see whether it&#8217;s feasible to use a combination [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-273" title="jquery-logo" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/06/jquery-logo.png" style="padding: 10px;" alt="jQuery logo" width="236" height="85" />During the course of my job I often find myself faced with the task of migrating information from an existing website to our own content management system.  In the past my approach to this task has been to assess the source code of the existing site and see whether it&#8217;s feasible to use a combination of curl, regular expressions and string manipulation.  Sometimes this is straightforward but increasingly this method is becoming less and less viable as it&#8217;s too intensive.</p>
<p>I&#8217;ve been using jQuery a lot recently and it occurred to me that I could use jQuery&#8217;s <a href="http://docs.jquery.com/Selectors">selectors</a> to target the information that I&#8217;m interested in a web page, and then using Ajax POST it to my own script that would be ready waiting to then do something useful with the data, e.g. validate it and save it in a database.  For educational purposes I was keen to keep this completely client-side if possible (except for a script to receive the information).  See later on for a server-side solution.</p>
<p>The situation I was up against was a page that had a heap of data in a table (about 90 items), but the table was interspersed with random images to split it up and make it more pleasing to the eye.  Fortunately for me, all of the data that I wanted was neatly wrapped in &lt;div class=&#8221;information&#8221;&gt;&lt;/div&gt; tags.  Selecting these div tags with jQuery is really easy by using $(&#8217;div.information&#8217;).</p>
<p>My first problem was that in order to use jQuery, the web page you&#8217;re looking at has to be using it.  Fortunately there&#8217;s a quick <a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a> called <a href="http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet/">jQuerify</a> that allows you to load jQuery onto any web page.  Once you&#8217;ve got that then you can write further bookmarklets of your own to do stuff.</p>
<p>So, my evil evil plan was to combine a jQuery selector, jQuery&#8217;s each() construct, and jQuery&#8217;s ajax support to post the content of each div to a &#8220;scraper&#8221; script, like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.information'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  $.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http://localhost/scraper.php'</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>
    data<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">innerHTML</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>I loaded my source page, clicked the jQuerify bookmarklet and then pasted the code above into the Firebug console (what, oh you&#8217;ll need that&#8230;) and it was flawless &#8230; except that the browser security model stepped in and prevented the ajax call because the XHTTPRequest object is not allowed to post information from one domain to another.  I was stuck - I googled around for a while looking for workarounds, and investigated the use of JSONP but the transport method seemed more weighted at retrieving information rather than posting it.</p>
<p>So, I was stuck with a simple question: &#8220;How can I get information from one site to another by using the browser?&#8221; - the simplest answer to this question is of course to have a form on the source website, that when submitted posts to the target.  Thanks to the power of JavaScript, modifying the DOM of a loaded web page is a doddle.  Therefore it should be simple to create a form on the page after it has loaded (client side, remember), create and populate some form fields with data and then submit the form to my scraper script.</p>
<p>Suddenly my intentions had outgrown a bookmarklet, but I would still need one for jQuerify and one for my &#8220;Scraper Utils&#8221;.  My new bookmarket simply asked jQuery to load a local JavaScript file in exactly the same was that jQuery was loaded in the first place:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">javascript<span style="color: #339933;">:</span>$.<span style="color: #660066;">getScript</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http://localhost/scraper.js'</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>Now I had the freedom of writing chunk loads of stuff in my local scraper.js file.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">Scraper <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>;
Scraper.<span style="color: #660066;">createForm</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> form <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'form'</span><span style="color: #009900;">&#41;</span>;
  form.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'method'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'POST'</span><span style="color: #009900;">&#41;</span>;
  form.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'action'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'http://localhost/scraper.php'</span><span style="color: #009900;">&#41;</span>;
  document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>form<span style="color: #009900;">&#41;</span>;
  <span style="color: #000066; font-weight: bold;">return</span> form;
<span style="color: #009900;">&#125;</span>
&nbsp;
Scraper.<span style="color: #660066;">createSubmitButton</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> button <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #009900;">&#41;</span>;
  button.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'type'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'submit'</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #000066; font-weight: bold;">return</span> button;
<span style="color: #009900;">&#125;</span>
&nbsp;
Scraper.<span style="color: #660066;">createFormField</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'textarea'</span><span style="color: #009900;">&#41;</span>;
  field.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'name'</span><span style="color: #339933;">,</span> <span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span>;
  field.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'rows'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span>;
  field.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'cols'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #000066; font-weight: bold;">return</span> field;
<span style="color: #009900;">&#125;</span>		
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> ScraperForm <span style="color: #339933;">=</span> Scraper.<span style="color: #660066;">createForm</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.information'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> ScraperForm.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>Scraper.<span style="color: #660066;">createFormField</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'data[]'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  field.<span style="color: #660066;">value</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">innerHTML</span>;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #006600; font-style: italic;">// Create a field that we can post with:</span>
ScraperForm.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>Scraper.<span style="color: #660066;">createSubmitButton</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>You can see here that I&#8217;ve set up a few functions, createForm(), createFormField(), createSubmitButton() and then at the bottom I wrap them all together with the $(&#8217;div.information&#8217;).each(&#8230;) construct.  The end result of this is that when I click my bookmarklet that includes the scraper.js script, a form is created at the bottom of the page and a textarea for each div.information is created that holds the innerHTML from that div.</p>
<p>Then, by clicking the Submit button, the browser posts all of that information across to http://localhost/scraper.php where I then collect the information from $_POST['data'] and poke it into a database.</p>
<p>It&#8217;s pretty rough and ready but could easily be extended to do other things like allow you to specify the selector and target URL for the post when you click the Scraper bookmarket.</p>
<h3>Server Side Solution</h3>
<p>On my travels I also came across the &#8220;PHP Simple HTML DOM Parser&#8221; which claims a similar ability like so:</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Create DOM from URL or file</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> file_get_html<span style="color: #009900;">&#40;</span><span style="">'http://www.google.com/'</span><span style="color: #009900;">&#41;</span>;
&nbsp;
<span style="color: #666666; font-style: italic;">// Find all images</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="">'img'</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$element</span><span style="color: #009900;">&#41;</span>
       <span style="color: #990000;">echo</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">src</span> <span style="color: #339933;">.</span> <span style="">'&lt;br/&gt;'</span>;
&nbsp;
<span style="color: #666666; font-style: italic;">// Find all links</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="">'a'</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$element</span><span style="color: #009900;">&#41;</span>
       <span style="color: #990000;">echo</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">href</span> <span style="color: #339933;">.</span> <span style="">'&lt;br/&gt;'</span>;</pre></div></div>

<p>You can get a hold of this from <a href="http://simplehtmldom.sourceforge.net/">Sourceforge at the PHP Simple HTML DOM Parser website</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/06/screen-scraping-with-jquery.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu and Lightning - not working, application seems buggy?</title>
		<link>http://www.guru.net.nz/blog/2009/01/ubuntu-and-lightning-not-working-application-seems-buggy.html</link>
		<comments>http://www.guru.net.nz/blog/2009/01/ubuntu-and-lightning-not-working-application-seems-buggy.html#comments</comments>
		<pubDate>Fri, 23 Jan 2009 10:09:32 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[lightning]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[thundebird]]></category>

		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=263</guid>
		<description><![CDATA[I&#8217;ve switched over to running Ubuntu 8.10 full time at work now.  The only things I miss are TortoiseSVN and the application integration with the desktop (Thunderbird/W32 for example lets you drag attachments onto the desktop).  Oh, and I miss TimeSnapper (classic - free download) too, but will get off my chuff and work out [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve switched over to running Ubuntu 8.10 full time at work now.  The only things I miss are TortoiseSVN and the application integration with the desktop (Thunderbird/W32 for example lets you drag attachments onto the desktop).  Oh, and I miss TimeSnapper (<a href="http://www.timesnapper.com/downloads/TimeSnapperClassicSetup.exe">classic - free download</a>) too, but will get off my chuff and work out an alternative using <a href="http://en.wikipedia.org/wiki/Xwd">Xwd</a>.</p>
<p>Anyway, at work we use the <a href="http://www.mozilla.org/projects/calendar/lightning/download.html">Lightning</a> calendar plugin for Thunderbird, with the <a href="https://addons.mozilla.org/en-US/thunderbird/addon/4631">Google Calendar provider</a> in order to collaborate on a calendar.  For the most part this works well as when not in the office you can fall back to <a href="http://calendar.google.com">Google Calendar</a>.</p>
<p>I went down the path of installing Lightning into Thunderbird (download the XPI, browse to it etc&#8230;) but after the installation Lightning seemed broken.  The UI was mostly there but it looked buggy and nothing worked.  After hunting around for a reason, I came across <a href="https://bugs.launchpad.net/ubuntu/+source/thunderbird/+bug/278853">this thread</a> that suggested that the problem was that the libstdc++5 package had to be installed.</p>
<p>I was skeptical, but after reading half a dozen &#8220;me too&#8221; posts where the problem had been fixed I got stuck in.</p>
<ol>
<li>Uninstall the Lightning plugin from Thunderbird</li>
<li>Open a terminal, and run this command: <strong>sudo aptitude install libstdc++5</strong></li>
<li>Reinstall Lightning from the XPI you downloaded</li>
</ol>
<p>Then things came to life nicely.  I was disappointed that the state of Lightning without libstdc++5 appeared to be a buggy application rather than a specific error.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/01/ubuntu-and-lightning-not-working-application-seems-buggy.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Goodbye Telecom</title>
		<link>http://www.guru.net.nz/blog/2009/01/goodbye-telecom.html</link>
		<comments>http://www.guru.net.nz/blog/2009/01/goodbye-telecom.html#comments</comments>
		<pubDate>Fri, 16 Jan 2009 20:39:16 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[orcon]]></category>

		<category><![CDATA[phone]]></category>

		<category><![CDATA[voip]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=261</guid>
		<description><![CDATA[Next week I&#8217;ll be porting my Telecom phone number to a VoIP provider (2talk) and then getting naked DSL provisioned on my line.  This setup should leave me with full speed broadband, the benefits of a VoIP line (I&#8217;ll blog about that later) and all the features that 2talk provide for my voice line for [...]]]></description>
			<content:encoded><![CDATA[<p>Next week I&#8217;ll be porting my Telecom phone number to a VoIP provider (<a href="http://2talk.co.nz">2talk</a>) and then getting naked DSL provisioned on my line.  This setup should leave me with full speed broadband, the benefits of a VoIP line (I&#8217;ll blog about that later) and all the features that 2talk provide for my voice line for only $85 per month.</p>
<p>Considering my broadband/phone bill currently sits at about $120 per month this will be a nice saving, plus an excuse to play with some technology :)  I&#8217;ll be using <a href="http://snap.net.nz">Snap</a> for the naked DSL, only because <a href="http://www.orcon.net.nz">Orcon</a> (my current provider) haven&#8217;t unbundled in Dunedin yet and it looks like it&#8217;ll be quite a while.</p>
<p>If you don&#8217;t mind a bit of downtime on your phone line or broadband service, the steps are:</p>
<ol>
<li>Port your phone number to 2talk.</li>
<li>Get naked DSL provisioned on your home line.</li>
<li>Configure your system so that your phone rings at home by connecting to 2talk&#8217;s servers</li>
</ol>
<p>You&#8217;ll need some hardware, and some charges (termination charges with your current broadband provider for example) may apply.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/01/goodbye-telecom.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>More on fail2ban</title>
		<link>http://www.guru.net.nz/blog/2009/01/more-on-fail2ban.html</link>
		<comments>http://www.guru.net.nz/blog/2009/01/more-on-fail2ban.html#comments</comments>
		<pubDate>Thu, 15 Jan 2009 09:42:56 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=257</guid>
		<description><![CDATA[A while ago I blogged about a SSH attack - this had been going on unnoticed for some time.  Taking my typical fire-and-forget (gently forced by a busy family life) I simply installed fail2ban and did nothing else.  Finally I was in a position where I had to research fail2ban a little more to figure [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I blogged about a SSH attack - this had been going on unnoticed for some time.  Taking my typical fire-and-forget (gently forced by a busy family life) I simply installed fail2ban and did nothing else.  Finally I was in a position where I had to research fail2ban a little more to figure out how to make it work.</p>
<p><strong>What is fail2ban?</strong></p>
<p>It&#8217;s a python script (that runs as a <a href="http://en.wikipedia.org/wiki/Daemon_(computer_software)">daemon</a>) which monitors log files in your /var/log file.  It monitors them for specific entries, for example &#8220;Failed password&#8221;, and then updates iptables rules to deny network access for the offending IP for a configured amount of time.</p>
<p>A good example of this is that if you try to ssh into my system three times unsuccessfully, you won&#8217;t be able to try again for 10 minutes.  This is sufficient to make automated brute force attacks useless.</p>
<p><strong>Do you need it?</strong></p>
<p>If<strong> </strong>you have a public-facing server with the ability to log into it (including web applications even) then you need this.  If you&#8217;re curious to see if you&#8217;ve been targeted for attacks, try running these commands as root on your server:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>auth.log | <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'Failed password'</span> | <span style="color: #c20cb9; font-weight: bold;">grep</span> sshd | <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1,$2}'</span> | <span style="color: #c20cb9; font-weight: bold;">sort</span> | <span style="color: #c20cb9; font-weight: bold;">uniq</span> <span style="color: #660033;">-c</span>
<span style="color: #c20cb9; font-weight: bold;">zcat</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>auth.log<span style="color: #000000; font-weight: bold;">*</span> | <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'Failed password'</span> | <span style="color: #c20cb9; font-weight: bold;">grep</span> sshd | <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1,$2}'</span> | <span style="color: #c20cb9; font-weight: bold;">sort</span> | <span style="color: #c20cb9; font-weight: bold;">uniq</span> <span style="color: #660033;">-c</span></pre></div></div>

<p>The first command examines your current auth.log file and the second examines your historical auth.log.[0-9] files.  In my recent history (prior to configuring fail2ban properly) I had over 6,000 failed SSH login attempts on a single day just after Christmas.</p>
<p><strong>What next?</strong><br />
The steps are:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> iptables fail2ban
bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>fail2ban start</pre></div></div>

<p>Now, you can check to see if it&#8217;s working by &#8220;pinging&#8221; the service:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> fail2ban-client <span style="color: #c20cb9; font-weight: bold;">ping</span>
Server replied: pong</pre></div></div>

<p>And you can get information on what&#8217;s currently been banned by examining the ssh &#8220;jail&#8221; - the jail is term used to describe the configuration and current black list for access from remote hosts:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> fail2ban-client status
Status
|- Number of jail:	<span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">`</span>- Jail list:		<span style="color: #c20cb9; font-weight: bold;">ssh</span>
bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> fail2ban-client status <span style="color: #c20cb9; font-weight: bold;">ssh</span>
Status <span style="color: #000000; font-weight: bold;">for</span> the jail: <span style="color: #c20cb9; font-weight: bold;">ssh</span>
|- filter
|  |- File list:	<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>auth.log
|  |- Currently failed:	0
|  <span style="color: #000000; font-weight: bold;">`</span>- Total failed:	<span style="color: #000000;">52</span>
<span style="color: #000000; font-weight: bold;">`</span>- action
   |- Currently banned:	0
   |  <span style="color: #000000; font-weight: bold;">`</span>- IP list:
   <span style="color: #000000; font-weight: bold;">`</span>- Total banned:	<span style="color: #000000;">7</span></pre></div></div>

<p>To test everything is working, simply try to log into your system incorrectly three times.  When you&#8217;ve done this and you look at the results of &#8220;fail2ban-client status ssh&#8221; you will see your remote IP in the list.  To unblock your IP, simply restart the fail2ban daemon (i.e. sudo /etc/init.d/fail2ban restart)</p>
<p>These pages were very useful when reading about fail2ban:</p>
<ul>
<li><a href="http://www.the-art-of-web.com/system/fail2ban/">The Art of Web ~ System: fail2ban and iptables</a></li>
<li><a href="http://www.fail2ban.org/wiki/index.php/MANUAL_0_8">The manual for fail2ban 0.8</a> (very readable)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/01/more-on-fail2ban.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Random Images</title>
		<link>http://www.guru.net.nz/blog/2009/01/random-images.html</link>
		<comments>http://www.guru.net.nz/blog/2009/01/random-images.html#comments</comments>
		<pubDate>Thu, 15 Jan 2009 08:52:37 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=250</guid>
		<description><![CDATA[Found these today on facebook, too good not to share&#8230;.
#1: A Stein-smashingly good time!

#2: I have days like these &#8230;

#3: Just too true

#4: Fandom

#5: White-belly-making-cereal

]]></description>
			<content:encoded><![CDATA[<p>Found these today on facebook, too good not to share&#8230;.</p>
<p>#1: A Stein-smashingly good time!</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817061_2312.jpg"><img class="alignnone size-full wp-image-251" title="n561728605_817061_2312" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817061_2312.jpg" alt="" width="500" height="375" /></a></p>
<p>#2: I have days like these &#8230;</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817077_8346.jpg"><img class="alignnone size-full wp-image-252" title="n561728605_817077_8346" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817077_8346.jpg" alt="" width="292" height="266" /></a></p>
<p>#3: Just too true</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817112_4036.jpg"><img class="alignnone size-full wp-image-253" title="n561728605_817112_4036" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817112_4036.jpg" alt="" width="604" height="191" /></a></p>
<p>#4: Fandom</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817115_4751.jpg"><img class="alignnone size-full wp-image-254" title="n561728605_817115_4751" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817115_4751.jpg" alt="" width="420" height="427" /></a></p>
<p>#5: White-belly-making-cereal</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817162_5313.jpg"><img class="alignnone size-full wp-image-255" title="n561728605_817162_5313" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817162_5313.jpg" alt="" width="266" height="400" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/01/random-images.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Letter to Parliament re Section 92</title>
		<link>http://www.guru.net.nz/blog/2008/12/letter-to-parliament-re-section-92.html</link>
		<comments>http://www.guru.net.nz/blog/2008/12/letter-to-parliament-re-section-92.html#comments</comments>
		<pubDate>Thu, 18 Dec 2008 00:09:03 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=244</guid>
		<description><![CDATA[In response to the proposed Section 92 of the Copyright Amendment Act &#8230; feel free to write one of these yourself, it&#8217;s free!  Also, check out the NZ Creative Freedom Foundation.
Rt. Hon Steven Joyce
Minister for Communications and Information Technology
Care of Distribution Services
Parliament Buildings
Wellington 6160
Dear Steven,
I am writing to you in urgency regarding the proposed Section [...]]]></description>
			<content:encoded><![CDATA[<p>In response to the proposed Section 92 of the Copyright Amendment Act &#8230; feel free to write one of these yourself, it&#8217;s free!  Also, check out the <a href="http://creativefreedom.org.nz/">NZ Creative Freedom Foundation</a>.</p>
<p style="padding-left: 30px;">Rt. Hon Steven Joyce<br />
Minister for Communications and Information Technology<br />
Care of Distribution Services<br />
Parliament Buildings<br />
Wellington 6160</p>
<p style="padding-left: 30px;">Dear Steven,</p>
<p style="padding-left: 30px;">I am writing to you in urgency regarding the proposed Section 92 of the Copyright Amendment Act that assumes guilt upon accusation, forcing the termination of internet connections and websites without evidence, a fair trial, or punishment for false acusations of copyright infringement.</p>
<p style="padding-left: 30px;">I work for a web development company and cannot let this “roll over” into law without voicing my protest. To know that any one of our clients, or indeed ourselves could be falsely accused without proof required and have our internet access terminated would have dire ramifications as our livelihoods and futures rely on providing these services.</p>
<p style="padding-left: 30px;">I urge you to carefully consider the ramifications of the proposed Section 92 and speak out on behalf of myself and others who have contacted you regarding this.</p>
<p style="padding-left: 30px;">I am available for further comment if required.</p>
<p style="padding-left: 30px;">Yours Sincerely</p>
<p style="padding-left: 30px;">Bob Brown<br />
Web Developer<br />
(my address)<br />
Dunedin</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2008/12/letter-to-parliament-re-section-92.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>The mind of a web developer</title>
		<link>http://www.guru.net.nz/blog/2008/10/the-mind-of-a-web-developer.html</link>
		<comments>http://www.guru.net.nz/blog/2008/10/the-mind-of-a-web-developer.html#comments</comments>
		<pubDate>Mon, 27 Oct 2008 01:43:36 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=236</guid>
		<description><![CDATA[While in the supermarket today I did a double take when I saw some &#8220;PHP Sauce&#8221; on the shelf next to me.  Of course, upon closer inspection I realised my folly.  I guess I can&#8217;t take a day off work without work chasing down my subconscious!
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2008/10/27-10-08_1322.jpg"><img class="alignright size-medium wp-image-237" title="PHP Sauce?" src="http://www.guru.net.nz/blog/wp-content/uploads/2008/10/27-10-08_1322-300x225.jpg" alt="" width="300" height="225" /></a>While in the supermarket today I did a double take when I saw some &#8220;PHP Sauce&#8221; on the shelf next to me.  Of course, upon closer inspection I realised my folly.  I guess I can&#8217;t take a day off work without work chasing down my subconscious!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2008/10/the-mind-of-a-web-developer.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>PHP tutorial - introduction to classes</title>
		<link>http://www.guru.net.nz/blog/2008/10/php-tutorial-introduction-to-classes.html</link>
		<comments>http://www.guru.net.nz/blog/2008/10/php-tutorial-introduction-to-classes.html#comments</comments>
		<pubDate>Mon, 13 Oct 2008 09:05:14 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[php]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=233</guid>
		<description><![CDATA[You might have noticed that I&#8217;ve migrated this blog to Wordpress - the main reason for doing so was to give me the ability to easily add pages to the blog so that I could keep my web dev tutorials in one place.
I&#8217;ve also just added the introduction to classes tutorial so go and check [...]]]></description>
			<content:encoded><![CDATA[<p>You might have noticed that I&#8217;ve migrated this blog to Wordpress - the main reason for doing so was to give me the ability to easily add pages to the blog so that I could keep my web dev tutorials in one place.</p>
<p>I&#8217;ve also just added the <a href="tutorials/intro-to-classes">introduction to classes</a> tutorial so go and check it out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2008/10/php-tutorial-introduction-to-classes.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Gettin’ hacked</title>
		<link>http://www.guru.net.nz/blog/2008/09/gettin-hacked.html</link>
		<comments>http://www.guru.net.nz/blog/2008/09/gettin-hacked.html#comments</comments>
		<pubDate>Sat, 27 Sep 2008 02:07:00 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/newblog/?p=187</guid>
		<description><![CDATA[I had an email this morning only five days after my billing cycle started saying that I was close to using my 15GB of data.  Normally we spend about 5-10GB, but 15GB in five days is exceptional.
I started digging and after ruling out intentional upload/download from inside my network (using wireshark on my LAN [...]]]></description>
			<content:encoded><![CDATA[<p>I had an email this morning only five days after my billing cycle started saying that I was close to using my 15GB of data.  Normally we spend about 5-10GB, but 15GB in five days is exceptional.</p>
<p>I started digging and after ruling out intentional upload/download from inside my network (using wireshark on my LAN segment) I then started looking at the wireless side of things.  I have a server on my LAN that is connected via wireless, and this is also a public facing server with sshd running on it.</p>
<p>I had a quick page through the /var/log/auth.log file and to my surprise I found repeated attempts to log in with various usernames (491 different ones so far) from various locations.  These were coming in at the rate of one every four seconds.  I can&#8217;t see how this would account for 15GB (or 1.5GB for that matter) but when I called Orcon they said they saw a definite increase in traffic over the last two days, which also corresponds to the first entry in the auth.log file.</p>
<p>Here&#8217;s what the log entries look like:<br /><span style="font-size:78%;"><span style="font-family: courier new;">Sep 27 13:29:59 pandora sshd[17366]: Failed password for invalid user oracle from 60.190.133.228 port 45662 ssh2<br />Sep 27 13:30:03 pandora sshd[17368]: Failed password for invalid user michael from 60.190.133.228 port 45857 ssh2<br />Sep 27 13:30:07 pandora sshd[17374]: Failed password for invalid user ftp from 60.190.133.228 port 46079 ssh2<br />Sep 27 13:30:12 pandora sshd[17376]: Failed password for invalid user test from 60.190.133.228 port 46301 ssh2<br />Sep 27 13:30:15 pandora sshd[17379]: Failed password for invalid user webmaster from 60.190.133.228 port 46553 ssh2<br /></span></span>and so on &#8230;</p>
<p>The requests have come from a range of IP addresses in China, Europe, Canada and Bangladesh.  It&#8217;s likely to be a distributed and targeted attack.</p>
<p>Interesting.  I did install fail2ban some time ago which I was told was supposed to prevent this kind of thing but it was an install-and-forget excercise.  I&#8217;ll have to research it a bit to find out how it actually works.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2008/09/gettin-hacked.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Screen recording with Linux</title>
		<link>http://www.guru.net.nz/blog/2008/09/screen-recording-with-linux.html</link>
		<comments>http://www.guru.net.nz/blog/2008/09/screen-recording-with-linux.html#comments</comments>
		<pubDate>Wed, 03 Sep 2008 09:33:00 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
		
		<category><![CDATA[linux]]></category>

		<category><![CDATA[mp3]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/newblog/?p=185</guid>
		<description><![CDATA[Hello to my future self - I&#8217;ve anticipated that I will be back in the future to read this post because I&#8217;m sure I would have forgotten how to do this stuff.  Firstly, a disclaimer - I am by no means an expert in this field, I just banged it &#8217;till it worked.  [...]]]></description>
			<content:encoded><![CDATA[<p>Hello to my future self - I&#8217;ve anticipated that I will be back in the future to read this post because I&#8217;m sure I would have forgotten how to do this stuff.  Firstly, a disclaimer - I am by no means an expert in this field, I just banged it &#8217;till it worked.  If you are having trouble doing similar things then I encourage you to post comments where they can be seen and responded to by all.</p>
<p>Secondly, an explanation of what it is I&#8217;m doing here.  A while back I saw some screencasts re <a href="http://www.inkscape.org/">Inkscape</a> at <a href="http://screencasters.heathenx.org/">screencasters.heathenx.org</a>.  I was impressed - it was a great way to teach people how to use Inkscape.</p>
<p>I had a play around and managed to get to the point where I can now do the following:</p>
<ul>
<li>Record my screen, or any particular window</li>
<li>Use my Logitech USB headset to record the audio</li>
<li>Play the resulting movie back, sound through speakers or headset</li>
</ul>
<p>For some reason I seem to be having a ridiculously hard time determining where the audio output goes for my Linux apps.  In Windows, when I plug my headset in, it becomes the default audio device for all applications.  Currently running applications still use their normal sound output, until restarted.  If I dig deep enough I might even be able to find settings in each program that allows me to specify which sound device (headset or sound card) should get the output.</p>
<p>In Linux (Ubuntu 8.04, Gnome to be precise) I discovered under System &gt; Preferences &gt; Sound an application that allows me to adjust the sound preferences.  In the dropdown list for each playback type I have seven possible playback device options (Auto, USB Audio, Intel ICH5, Intel ICH5 - IEC958, ALSA, OSS &amp; PulseAudio).  It seems that if I set them all to USB Audio then I get lucky and most things play through the headphones.  Some things, especially the Adobe Flash Player plugin insists on playing through my desktop speakers regardless.  I saw someone complaining that this was Adobe&#8217;s fault, not Linux but I can&#8217;t comment.  In order to avoid all this confusion I found out how to specify the sound device that you want to use for each operation.  This is pretty much the crux of this post.</p>
<p>Anyway, here&#8217;s what I did &#8230;</p>
<h2>Recorded My Desktop</h2>
<p>There&#8217;s a package in the Ubuntu universe repository called recordmydesktop which as the name suggests can be used to record your desktop, with sound.  This is great for making recordings of how to do things to share with others.  I installed the recordmydesktop package, along with the GTK front end to save me having to look up the commands all the time..</p>
<pre>bob@sparkie:~$ sudo apt-get install recordmydesktop gtk-recordmydesktop</pre>
<p><a href="http://www.guru.net.nz/blog/uploaded_images/Screenshot-recordMyDesktop-715177.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://www.guru.net.nz/blog/uploaded_images/Screenshot-recordMyDesktop-715167.png" border="0" alt="" /></a>Once installed I then hit Alt-F2 (to bring up the Run  Application dialog) and typed in gtk-recordmydesktop.</p>
<p>It seemed that by default it was trying to record sound via the mic input on my sound card.  Fat chance it would have had because I don&#8217;t have a mic in my soundcard, instead I have a USB headset.</p>
<p>After Googling around I discovered that if I click the Advanced button in gtk-recordmydesktop I could then enter the sound device to use to capture audio.  I used the device name &#8220;plughw:Headset,0,0&#8243; and was able to record sound via my USB headset.</p>
<p>The key to this was finding out what to type in for the device name.  I discovered the aplay and arecord utilities that allow you to play and record sound.  Each utility has a -l switch which lists the available devices.  Here&#8217;s the output of my arecord -l:</p>
<pre>bob@sparkie:~$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: ICH5 [Intel ICH5], device 0: Intel ICH [Intel ICH5]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: ICH5 [Intel ICH5], device 1: Intel ICH - MIC ADC [Intel ICH5 - MIC ADC]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: ICH5 [Intel ICH5], device 2: Intel ICH - MIC2 ADC [Intel ICH5 - MIC2 ADC]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: ICH5 [Intel ICH5], device 3: Intel ICH - ADC2 [Intel ICH5 - ADC2]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: Headset [Logitech USB Headset], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0</pre>
<p>You can see beside each &#8220;card&#8221; there is a device name, either ICH5 (my sound card) or Headset.  Each of those cards has a number of subdevices - in the case of the sound card you can see there are four possible subdevices I could have chosen (numbered 0 to 3) and for the headset it&#8217;s a free ride because there&#8217;s only one to choose from (as I would have expected).</p>
<p>So, now that plughw:Headset,0,0 should make a bit more sense.  With that all set up, I hit record, wiggled my mouse around, spoke some gibberish and created a .ogg file of my session.</p>
<h2>Sound Recording and Playback</h2>
<p>While I was debugging my sound devices I fiddled around a bit with arecord and aplay.  Using the command <span style="font-size:85%;"><span style="font-family: courier new;">arecord -Dplughw:Headset,0,0 -f S16_LE -c2 -r44100 &gt; myfile.wav</span></span> I created a 44kHz wav file using the headset mic as my recording device.</p>
<p>When I played it back with aplay myfile.wav, it played through my desktop speakers.  To play it through my headset I just specified the device name as I did with the arecord command, thus  <span style="font-family: courier new;font-size:85%;">aplay -Dplughw:Headset,0 myfile.wav</span></p>
<p>If you want to use mplayer to play something back using a specific device for audio output, this command will do the trick for you:<span style="font-size:85%;"><span style="font-family: courier new;"> mplayer -ao alsa:device=hw=1.0 ep069.flv</span></span>.  Device 1.0 is card #1, device 0 - and that&#8217;s the headset.</p>
<p>If you need to adjust the volume, I found you can use the alsamixer.  To control each card you can specify which one with the -c switch.  In my case card 0 is the default and internal sound card, and card 1 is the USB Headset: <span style="font-size:85%;"><span style="font-family: courier new;">alsamixer -c 1</span></span></p>
<p>That&#8217;s all for now!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2008/09/screen-recording-with-linux.html/feed</wfw:commentRss>
		</item>
	<lastBuildDate>Mon, 15 Jun 2009 17:40:02 PDT</lastBuildDate></channel>
</rss>
