<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Brian C. Lane</title><link>http://brianlane.com</link><description></description><atom:link href="http://brianlane.com/feeds/all.rss.xml" rel="self"></atom:link><lastBuildDate>Thu, 16 Feb 2012 00:00:00 -0000</lastBuildDate><item><title>NASCAR Countdown for iPhone</title><link>http://brianlane.com/nascar-iphone.html</link><description>&lt;p&gt;The NASCAR Countdown app displays a countdown to the next &lt;a class="reference external" href="http://www.nascar.com"&gt;NASCAR&lt;/a&gt; race, the
name of the race and the television network carrying the race. On the flip side
all of the races for the season are listed, and tapping on one of them
will go to the nascar.com website for that track. The application now includes
all of the Sprint Cup, Nationwide Series and Camping World Truck races.&lt;/p&gt;
&lt;img alt="images/nascar-iphone/Screenshot-front.png" src="images/nascar-iphone/Screenshot-front.png" style="width: 250px;" /&gt;
&lt;img alt="images/nascar-iphone/Screenshot-flip.png" src="images/nascar-iphone/Screenshot-flip.png" style="width: 250px;" /&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;iPhone or iPod&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;em&gt;v1.0&lt;/em&gt; Initial release&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v1.1&lt;/em&gt; Added Nationwide and Camping World Truck races. Added date of next
race above the countdown. Added details to the list of races.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v1.5&lt;/em&gt; Updated for 2012 Season&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v1.6&lt;/em&gt; Fixed a couple uninitialized variables. Hopefully fixing the crashes
that some users were seeing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;&lt;strong&gt;Crash Reports&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you are experiencing crashes please send me a crash report by following the
following steps from Apple Technical Note &lt;a class="reference external" href="https://developer.apple.com/library/ios/#technotes/tn2151/_index.html"&gt;TN2151&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Synchronize the device using iTunes. This will copy the crash report to your computer.&lt;/li&gt;
&lt;li&gt;Find the NascarCountdown .crash file in the following directory, based on your Operating System&lt;/li&gt;
&lt;li&gt;Mac OS X: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/Library/Logs/CrashReporter/MobileDevice/&amp;lt;DEVICE_NAME&amp;gt;&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Windows XP: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C:\Documents&lt;/span&gt; and &lt;span class="pre"&gt;Settings\&amp;lt;USERNAME&amp;gt;\Application&lt;/span&gt; Data\Apple &lt;span class="pre"&gt;Computer\Logs\CrashReporter\MobileDevice\&amp;lt;DEVICE_NAME&amp;gt;&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Windows Vista or 7: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C:\Users\&amp;lt;USERNAME&amp;gt;\AppData\Roaming\Apple&lt;/span&gt; &lt;span class="pre"&gt;Computer\Logs\CrashReporter\MobileDevice\&amp;lt;DEVICE_NAME&amp;gt;&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;USERNAME&amp;gt; is the user's login name for the computer. &amp;lt;DEVICE_NAME&amp;gt; is the name of the iPod touch or iPhone, for example, &amp;quot;John's iPhone&amp;quot;.&lt;/p&gt;
&lt;p&gt;Email it to me at nascar &amp;#64; this domain name. Thanks, for helping out!&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://itunes.apple.com/us/app/nascar-countdown/id353416229?mt=8"&gt;&lt;img alt="images/misc/appstore.png" src="images/misc/appstore.png" /&gt;&lt;/a&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 16 Feb 2012 00:00:00 -0000</pubDate><category>iPhone</category><category>NASCAR</category></item><item><title>Moving a BackupPC Pool</title><link>http://brianlane.com/moving-a-backuppc-pool.html</link><description>&lt;p&gt;I have been using &lt;a class="reference external" href="http://backuppc.sourceforge.net"&gt;BackupPC&lt;/a&gt; to automatically back up the systems on my LAN
for years now. It started out with a 3x250GB RAID5 as the storage pool and when
I ran out of space on that I added another disk to bring it up to about 700GB.
&lt;a class="reference external" href="http://backuppc.sourceforge.net"&gt;BackupPC&lt;/a&gt; does an excellent job of pooling common files together so that they
don't take up extra space. This is especially useful if you are backing up
system files on multiple systems running the same OS release.&lt;/p&gt;
&lt;p&gt;The way it achieves this is through the use of hardlinks. A hardlink references
the inode of the original file instead of making a copy of its data. This only
works on a single filesystem since inodes are not unique between filesystems.
When you have 700GB of data backed up this results in &lt;em&gt;alot&lt;/em&gt; of hardlinks. So
many in fact that none of the file copy tools available can deal with copying
them to a new filesystem.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://backuppc.sourceforge.net"&gt;BackupPC&lt;/a&gt; also keeps track of how full the pool is, and when it hit about
95% I started getting emails about it not backing up systems. As it expires
old backups it would drop back down to 90% but I realized it was finally time
to tackle the problem of moving the pool to a new RAID1 array. I decided to
go with RAID1 of 2T drives instead of a RAID5 because as drives get bigger the
chances of hitting an unrecoverable error increase. This means that when a 4
disk RAID5 loses a disk and you insert a new one it becomes more likely that
you will hit another error before the recovery is complete. RAID10 helps
mitigate this somewhat, using a RAID5 of mirrors, but that pretty much defeats
the 'Inexpensive' part of RAID. The article &amp;quot;&lt;cite&gt;RAID's Days May Be Numbered&lt;/cite&gt;&amp;quot;
covers these issues pretty well.&lt;/p&gt;
&lt;p&gt;I am using Linux's mdraid to manage the array. This array was originally
created while running Debian on an old single CPU 2.8GHz Celeron. Over the
years I have upgraded the hardware and even switched to using Fedora without
any problems recognizing the RAID array. I don't remember exactly why, but
it was setup as a single LVM physical volume with a single VG/LV on top of
that using ext3. These days I typically skip LVM and setup ext4 right on the
disk to eliminate any unneeded complexity. But in this case I'm glad I had
LVM setup, and will continue to use it for large blocks of extra disk.&lt;/p&gt;
&lt;p&gt;The most common solution to moving a &lt;a class="reference external" href="http://backuppc.sourceforge.net"&gt;BackupPC&lt;/a&gt; pool is to use tar to pipe to
another tar process that uncompresses it on the target filesystem. tar knows
how to handle hardlinks, devices, etc.  So it is a god choice for copying
things around when you can't use rsync. But when I gave this a try it ran
fairly quickly up to about 90% and then slowed way down. So slow that I could
count the number of blocks being transferred using df. According to atop and
iotop it was spending all of its time reading and very little time writing. I'm
not sure why, and didn't feel like stracing it to figure it out.&lt;/p&gt;
&lt;p&gt;The next most common method is using dd to copy the filesystem over and then
use resize tools to grow it. This would probably have worked, but I was
concerned about it also copying UUIDs and ending up with a cloned fs and a
confused fstab. About this time I realized it was actually on LVM and that
I could use its tools to handle the move.&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="http://tldp.org/HOWTO/LVM-HOWTO/removeadisk.html"&gt;LVM Howto&lt;/a&gt; provides some pretty good examples of how to do things with
LVM, including how to remove a disk. Section 13.5.2 covers moving things to
a new disk. Here's what I did (note, this worked for me, may not for you,
YMMV). I'd remind you to backup your data, but in this case that's exactly
what we're trying to accomplish, so...&lt;/p&gt;
&lt;p&gt;I used parted to create a GPT disk label and partition the whole drives into
a single partition. I also set the raid flag on the partition.&lt;/p&gt;
&lt;p&gt;I setup the new array as /dev/md3 like this:&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;mdadm &lt;span class="pre"&gt;--create&lt;/span&gt; /dev/md3 &lt;span class="pre"&gt;--level=raid1&lt;/span&gt; &lt;span class="pre"&gt;--raid-devices=2&lt;/span&gt; /dev/sdb1 /dev/sdc1&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;In order to prevent mdadm from syncing the disks immediately I froze the
sync:&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;echo frozen &amp;gt; /sys/blocl/md3/md/sync_action&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;This may not have been needed, but seems like a good idea to get the actual
data moved over first, then let it sync.&lt;/p&gt;
&lt;p&gt;Don't forget to shut down backuppc and unmount the existing pool. All of
these steps should be done on an unmounted system, just to be safe.&lt;/p&gt;
&lt;p&gt;The existing RAID5 is called raid5-vol1 and it is on /dev/md0, I moved the
data over to the new array using LVM tools:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;pvcreate /dev/md3
vgextend raid5-vol1 /dev/md3
pvmove /dev/md0 /dev/md3
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The move took about 4 hours and has regular updates. I suggest running all
of this inside screen, just in case your ssh session/teminal/whatever goes
away.&lt;/p&gt;
&lt;p&gt;After that is done I removed the old array from the VG:&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;vgreduce &lt;span class="pre"&gt;raid5-vol1&lt;/span&gt; /dev/md0A&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Now all the data is on the new array, but it is not able to take advantage
of the extra space of the larger drives. So we need to resize the lv. Run
vgdisplay and look at the 'Total PE', this is the maximum number of PE's
available. You will notice that the Alloc PE matches the size of the old
array. We are going to resize it to use all of them with:&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;lvresize &lt;span class="pre"&gt;-l&lt;/span&gt; xxxxxx &lt;span class="pre"&gt;/dev/raid5-vol1/raid5&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Where xxxxxx is the Total PE number. This operation is very quick. Now you
are ready to resize the filesystem itself. I'm using ext3 so I use the e2fs
tools to operate on it, first running a filesystem check to make sure there
are no errors on the fs and then resizing it to use all the available space
on the underlying device.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;e2fsck -f /dev/radi5-vol1/raid5
resize2fs -p /dev/raid5-vol1/raid5
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When that finishes (took about an hour and a half for me) you can then
re-enable the array sync using:&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;echo check &amp;gt; /sys/blocl/md3/md/sync_action&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;And then mount your new pool and restart backuppc.&lt;/p&gt;
&lt;p&gt;Pay careful attention to the PE number you use when resizing. It will ask you
if you make a mistake and try to shrink it (yes, I found this out when using
the -L option instead of -l). It is also easy to cut and paste the wrong number
and not grow it as much as you thought. Again, I did this, only noticing when
reviewing things for this article. I must have picked the free space number
because I still had about 700GB of PE's available. I followed the steps to
lvresize and resize2fs above and am now using the full amount of space available.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 15 Sep 2011 09:05:00 -0000</pubDate><category>Linux</category><category>BackupPC</category><category>LVM</category></item><item><title>New MovieLandmarks Update</title><link>http://brianlane.com/new-movielandmarks-update.html</link><description>&lt;p&gt;&lt;a class="reference external" href="http://www.movielandmarks.com"&gt;Movie Landmarks&lt;/a&gt; is back online. I think this is the 5th iteration of the
project that I originally started back in 2006. It started out as a PHP app,
morphed into a python wsgi application. It was always backed by a mysql db
with lots of interactive features. For this redesign I've dropped all of that
extra stuff and simplified things.&lt;/p&gt;
&lt;p&gt;I threw out the database and replaced it with a couple of python dictionaries
holding the landmark information and another with the movie data. I use
&lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; to create the JSON and html files use for the site. This only needs
to be run when I add new landmarks or movies.&lt;/p&gt;
&lt;p&gt;The site now runs using Javascript to control the map and load the information
pages. &lt;a class="reference external" href="http://jquery.com"&gt;jQuery&lt;/a&gt; is used for the accordion on the left and Google Maps for
the mapping. Clustering was one of the early features I wanted to implement, and
I tried a variety of server side solutions but none of them worked as well as
I liked. Google finally added clustering to their mapping API a couple years
ago so that is what I am using now.&lt;/p&gt;
&lt;p&gt;The site should run faster than previous implementations. Not being dependant
on a database for its content allows the html to be easily cached using various
methods. Currently I'm using &lt;a class="reference external" href="http://cloudflare.com"&gt;cloudflare&lt;/a&gt; to speed things up.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 02 Jul 2011 09:05:00 -0000</pubDate><category>MovieLandmarks</category><category>Python</category><category>Javascript</category></item><item><title>Local time for mutt email display</title><link>http://brianlane.com/local-time-for-mutt-email-display.html</link><description>&lt;p&gt;I use &lt;a class="reference external" href="http://mutt.org"&gt;mutt&lt;/a&gt; as my email client. Something that has recently been bugging me
is that when reading a message it displays the original Date: header with the
sender's timezone. Since I work with people in several different zones I am
constantly having to do timezone math when looking at these. So I decided to
fix that with a bit of &lt;a class="reference external" href="http://python.org"&gt;python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of mutt's features is that you can feed every email you view through a
filter by using the display_filter setting. So I created a small python app
using the email module to parse the message, grab the original date and add
a new header named X-Date: that has my local time in it. It looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    Copyright 2011 by Brian C. Lane&lt;/span&gt;
&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;email&lt;/span&gt;

&lt;span class="n"&gt;raw_msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message_from_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw_msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;email.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;mktime_tz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parsedate_tz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;formatdate&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;# Convert to local TZ&lt;/span&gt;
        &lt;span class="n"&gt;tz_tuple&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsedate_tz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;epoch_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mktime_tz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tz_tuple&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;X-Date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;formatdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;epoch_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;localtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt; &lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cStringIO&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StringIO&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;email.generator&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Generator&lt;/span&gt;
        &lt;span class="n"&gt;fp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StringIO&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Generator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mangle_from_&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxheaderlen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getvalue&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;traceback&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;traceback&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format_exc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw_msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c"&gt;# just write it out&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw_msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add this to your muttrc file to use it:
&lt;tt class="docutils literal"&gt;set &lt;span class="pre"&gt;display_filter=&amp;quot;$HOME/.mutt/local-date.py&amp;quot;&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Messages are passed to the filter on stdin and read from stdout so I read in
the whole message first, parse it for the Date and if it doesn't exist just
output the raw message on stdout and exit. If Date is there I use a couple of
methods from the email module to convert the original time to UTC and then
add the new header using the local timezone. I then write the parsed message
to stdout and exit. If there are any errors I output the traceback and then
the original message.&lt;/p&gt;
&lt;p&gt;Note that the message on disk is never changed. Processing happens in memory as
you are reading them so the original is safe from accidents.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 30 Jun 2011 17:30:00 -0000</pubDate><category>mutt</category><category>Python</category><category>Linux</category></item><item><title>Changes to the Webpage and Blog</title><link>http://brianlane.com/changes-to-the-webpage-and-blog.html</link><description>&lt;p&gt;As you may have noticed my webpages have changed a bit today. After about 6
years I decided it was time to revamp things a bit. The old site was all
written in plain html with an attempt at reference link usage. I decided
to rewrite in &lt;a class="reference external" href="http://docutils.sourceforge.net/rst.html"&gt;Restructured Text&lt;/a&gt; using &lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt; and some kind of
template language. I decided to do some searching before writing my own
and found the &lt;a class="reference external" href="http://docs.notmyidea.org/alexis/pelican/"&gt;Pelican&lt;/a&gt; project which fit what I wanted to do perfectly.&lt;/p&gt;
&lt;p&gt;I used the included the conversion tool to convert my Wordpress blog
posts over to ReST, added some &lt;a class="reference external" href="http://lighttpd.net"&gt;lighttpd&lt;/a&gt; url redirection rules to make
sure incoming links aren't totally broken.&lt;/p&gt;
&lt;p&gt;I didn't bother to copy over the old blog comments, there weren't that
many of them. All comments are now handled via &lt;a class="reference external" href="http://disqus.com"&gt;Disqus&lt;/a&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 05 Jun 2011 00:00:00 -0000</pubDate><category>Pelican</category><category>ReST</category><category>Webpages</category></item><item><title>AIS Parser SDK is now Free</title><link>http://brianlane.com/ais-parser-sdk-is-now-free.html</link><description>&lt;p&gt;I have decided to discontinue sales of my
&lt;a class="reference external" href="http://www.aisparser.com"&gt;AIS Parser SDK&lt;/a&gt; and have released the
code under the BSD License on
&lt;a class="reference external" href="https://github.com/bcl/aisparser/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Mon, 27 Dec 2010 09:56:00 -0000</pubDate><category>AIS</category></item><item><title>Nice %changelog entries</title><link>http://brianlane.com/nice-changelog-entries.html</link><description>&lt;p&gt;When updating a rpm package it is nice to include a summary of the
changes made since the last time. anaconda does this with a nifty
script written by dcantrell called
&lt;a class="reference external" href="http://git.fedorahosted.org/git/?p=anaconda.git;a=blob;f=scripts/makebumpver;hb=HEAD"&gt;makebumpver&lt;/a&gt;
which also enforces some RHEL rules and handles changing the
version. I only needed the changelog part of this so I modified the
script a bit to remove the extras:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/python&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# git-changelog - Output a rpm changelog&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Copyright (C) 2009-2010  Red Hat, Inc.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# This program is free software; you can redistribute it and/or modify&lt;/span&gt;
&lt;span class="c"&gt;# it under the terms of the GNU Lesser General Public License as published&lt;/span&gt;
&lt;span class="c"&gt;# by the Free Software Foundation; either version 2.1 of the License, or&lt;/span&gt;
&lt;span class="c"&gt;# (at your option) any later version.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# This program is distributed in the hope that it will be useful,&lt;/span&gt;
&lt;span class="c"&gt;# but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/span&gt;
&lt;span class="c"&gt;# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;/span&gt;
&lt;span class="c"&gt;# GNU Lesser General Public License for more details.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# You should have received a copy of the GNU Lesser General Public License&lt;/span&gt;
&lt;span class="c"&gt;# along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Author: David Cantrell &amp;lt;dcantrell@redhat.com&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;# Author: Brian C. Lane &amp;lt;bcl@redhat.com&amp;gt;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;subprocess&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;textwrap&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;optparse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OptionParser&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChangeLog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_getCommitDetail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;proc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Popen&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;log&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;-1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="s"&gt;&amp;quot;--pretty=format:&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                &lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PIPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PIPE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;communicate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;@&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;@&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;..&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;proc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Popen&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;log&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;--pretty=oneline&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                &lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PIPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PIPE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;communicate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;l10n: &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; \
                                 &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Merge commit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; \
                                 &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Merge branch&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;commit&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_getCommitDetail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;long&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_getCommitDetail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;%b&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_getCommitDetail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;%aE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;)&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;formatLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLog&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;sublines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;textwrap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;77&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;- &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;sublines&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sublines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;subline&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sublines&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]:&lt;/span&gt;
                    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;  &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;subline&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OptionParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-t&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;--tag&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;tag&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Last tag, changelog is commits after this tag&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;cl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChangeLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;cl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;formatLog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I've copied my version of this
&lt;a class="reference external" href="http://bcl.fedorapeople.org/scripts/git-changelog"&gt;here&lt;/a&gt; for
easy downloading. Run it like this -
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;git-changelog&lt;/span&gt; &lt;span class="pre"&gt;-t&lt;/span&gt; &lt;span class="pre"&gt;livecd-tools-15.0&lt;/span&gt;&lt;/tt&gt; and the output is:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
- Fix incomplete rename of freespace variable (#656154) (fgrose)
- Bump version to 15.1 (bcl)
- Create tmpdir if it doesn't exist (#658632) (bcl)
- Wrap subprocess.call() so we can capture all command output for debugging. (jlaska)
- Work with the logging settings when emitting progress. (jlaska)
- Add a quiet option to surpress stdout. Adjust handle\_logfile to not surpress stdout. (jlaska)
- Fix partition number selection for MMC bus devices (#587411) (fgrose)
- Fix disk space estimation errors (#656154) (fgrose)
- Tolerate empty transactions (lkundrak)
- Merge livecd-creator and image-creator (lkundrak)
- Cleanup if/then blocks (#652522) (fgrose)
&lt;/pre&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 02 Dec 2010 16:53:00 -0000</pubDate><category>Fedora</category><category>git</category></item><item><title>AIS feed is up again</title><link>http://brianlane.com/ais-feed-is-up-again.html</link><description>&lt;p&gt;A few weeks back my ancient Compaq laptop stopped booting (two LOUD beeps, no
display, no drive noises). This system has been used in the garage to act as a
serial to WiFi bridge for my AIS receiver, and to log temperatures for the
garage and freezer temps you see &lt;a class="reference external" href="http://www.digitemp.com"&gt;at digitemp.com&lt;/a&gt;.
The AIS data feeds the &lt;a class="reference external" href="http://live.aisparser.com"&gt;Live AIS view&lt;/a&gt; of Puget
Sound.&lt;/p&gt;
&lt;p&gt;The laptop was exiled to the garage after its power connector broke for the 3rd
time and I had to hard-wire it by soldering it directly to the motherboard. Its
battery hadn't been holding a charge all that well either. I installed Fedora
11 or 12 on it, choosing to encrypt the whole drive. This ended up being a bit
of a mistake, after power outages I would have to try to remember the
passphrase, and after it finally failed I pulled the drive to read it with a
USB to IDE adapter and was stumped until I looked at my password list and
realized I had written it down.&lt;/p&gt;
&lt;p&gt;My first attempt to replace it was to use a &lt;a class="reference external" href="http://www.saelig.com/product/BRD019.htm"&gt;serial to Ethernet board from
Wiznet&lt;/a&gt;. It looks like the perfect
solution, 2 ports for only $30. The first hurdle was configuring the board. The
manual is full of details on howto set it up via the serial port, and it didn't
come request an IP from my DHCP server (a &lt;a class="reference external" href="http://www.amazon.com/gp/product/B000BTL0OA?ie=UTF8&amp;amp;tag=movielandm-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000BTL0OA"&gt;WRT54GL&lt;/a&gt;
running &lt;a class="reference external" href="http://www.polarcloud.com/tomato"&gt;Tomato&lt;/a&gt;). I futzed around with
serial cables and solder, swapping pins, creating gender changers, I even made
a really nice crossover cable. And still got no response back from the board.&lt;/p&gt;
&lt;p&gt;I broke down and fired up their configuration utility. Which, it ends up,
configures it via the network port. Since my XP KVM instance is NAT'd their
scan (probably a simple UDP broadcast) didn't get a response. The examples in
the manual used 192.168.11.X addresses, so I added an alias to eth0 and nmap'd
the subnet which returned an active device at 192.168.11.100 which seems to be
the default static IP assignment of these &lt;a class="reference external" href="http://www.saelig.com/product/BRD019.htm"&gt;Wiznet boards&lt;/a&gt;. After that it was a matter of
manually specifying the IP for their config tool and setting up the real IP and
serial port baudrates.&lt;/p&gt;
&lt;p&gt;With my faith in hardware partially restored I plugged in one of my &lt;a class="reference external" href="http://www.ibuttonlink.com"&gt;Link45
1-wire adatpers&lt;/a&gt; and tried to talk to it. No
dice. No matter what baudrate I tried it wouldn't respond. I plugged it into my
FTDI based USB to serial adapter and it worked fine (9600bps, send it an h and
it prints out the help screen). I checked the config screen again. No options
to change DTR (1-wire adapters typically are powered by the DTR line). I pulled
out my voltmeter and started probing the board. Weird voltage levels on the DTR
pin, kinda like it isn't connected to anything.&lt;/p&gt;
&lt;p&gt;I then notice that the RS232 converter chip they are using is a 3232, which I'm
familiar with, having used it in a few projects myself. It is a 4 port (2 ins
and 2 outs) RS232 level converter. A nice chip. Except that it doesn't have
enough pins to implement a full RS232 port, and the Wiznet device has RTS/CTS
connected. I read the manual again, and right there is a nice table with the
pinouts. Sure enough, no DTR line. So much for that solution.&lt;/p&gt;
&lt;p&gt;I ended up taking an old 2U server I had lying around (Which surprised me by
being an AMD 1.3GHz system with 1G RAM). I had a spare &lt;a class="reference external" href="http://www.amazon.com/gp/product/B000BTL0OA?ie=UTF8&amp;amp;tag=movielandm-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000BTL0OA"&gt;WRT54GL&lt;/a&gt;,
coincidentally I had modified it to add serial ports and ran into the same
problem -- no DTR line. I setup &lt;a class="reference external" href="http://www.dd-wrt.com/site/index"&gt;DD-WRT&lt;/a&gt; on
it and configured it as a client for my existing WiFi network. Plugged in the
server and presto, I was up and running from the garage again. I re-installed
the system with &lt;a class="reference external" href="http://www.fedoraproject.org"&gt;Fedora 14&lt;/a&gt;, this time not
encrypting the drive -- there is no console on it, I could hook up a spare PS/2
keyboard but blind-typing the passphrase after a power outage doesn't appeal to
me. Initially I tried using &lt;a class="reference external" href="http://boot.fedoraproject.org"&gt;boot.fedoraproject.org&lt;/a&gt; for the install, but it was taking too long
so I did a USB boot instead. This turned out to be just about as slow as bfo
but it finally finished after letting it run overnight.&lt;/p&gt;
&lt;p&gt;I immediately added the new system to my backuppc configuration so I don't have
to worry about losing any customizations I may make. The only thing missing
right now is a UPS. My last &lt;a class="reference external" href="http://www.amazon.com/gp/product/B00006BBIL?ie=UTF8&amp;amp;tag=movielandm-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B00006BBIL"&gt;APC 500&lt;/a&gt;
died this week so its time to pick up a couple of new ones, probably smaller
CyberPower units since their &lt;a class="reference external" href="http://www.amazon.com/gp/product/B000FBK3QK?ie=UTF8&amp;amp;tag=movielandm-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000FBK3QK"&gt;1500VA&lt;/a&gt;
ones have been working well for me on my servers.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 07 Nov 2010 14:53:00 -0000</pubDate><category>AIS</category><category>Fedora</category><category>Linux</category></item><item><title>Using RAID to Escape Disaster</title><link>http://brianlane.com/using-raid-to-escape-disaster.html</link><description>&lt;p&gt;Failed hard drives are inevitable. Especially when the drive in
question was manufactured on November 27, 2001. You know the time
has come to replace it when your log files start filling up with
errors like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Oct 28 03:53:05 cat kernel:         res 51/40:00:fc:33:4e/00:00:00:00:00/e0 Emask 0x9 (media error)
Oct 29 16:06:46 cat smartd[24427]: Device: /dev/sdb [SAT], FAILED SMART self-check. BACK UP DATA NOW!
&lt;/pre&gt;
&lt;p&gt;Failure is inescapable. Everything fails eventually, computers, people,
electronics. This is the only constant in life. It is only a question of when.
In my case this 40GB drive had served me well in multiple computers and as part
of a RAID5 array for my &lt;a class="reference external" href="http://www.linuxjournal.com/article.php?sid=6558"&gt;Linux Journal article&lt;/a&gt;. In its final installation
it was part of a 2 disk RAID1 in cat, my webserver. cat runs Fedora 13 and a
minimal set of software for serving up my webpages, including this blog. cat
was built using spare parts, its job isn't hard and space requirements aren't
large. Good logging and reporting are important, they help you anticipate the
impending doom. On my systems I am running the smartd daemon to monitor drive
health as well as epylog to parse all my logfiles and email me nightly results.&lt;/p&gt;
&lt;p&gt;Cat was setup running Fedora 13 on 2 drives with 3 partitions. &lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;/&lt;/tt&gt;
and swap. &lt;tt class="docutils literal"&gt;/&lt;/tt&gt; was setup as a 2 disk RAID1 and &lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt; was actually
&lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;/boot2&lt;/tt&gt; because at the time I was unsure if grub could boot
from a RAID (yes, it can, and that's another post entirely). The partitioning
looked like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[root&amp;#64;cat ~]# parted -l
Model: ATA Maxtor 5T040H4 (scsi)
Disk /dev/sda: 41.0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system     Name  Flags
 1      1049kB  525MB   524MB   ext4                  boot
 2      525MB   2622MB  2097MB  linux-swap(v1)
 3      2622MB  41.0GB  38.4GB                        raid
&lt;/pre&gt;
&lt;p&gt;When the errors showed up I jumped over to Amazon Prime and found a pretty good
deal on a pair of &lt;a class="reference external" href="http://www.amazon.com/gp/product/B001VKYA5E?ie=UTF8&amp;amp;tag=movielandm-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B001VKYA5E"&gt;Seagate 500 GB Drives&lt;/a&gt;.
I had them the next day, but didn't have time to start the process of swapping
them in and expanding the storage. Instead I removed the failing drive from the
array using &lt;tt class="docutils literal"&gt;mdadm &lt;span class="pre"&gt;--manage&lt;/span&gt; &lt;span class="pre"&gt;--set-faulty&lt;/span&gt; /dev/md0 /dev/sdb3&lt;/tt&gt;, as well as
removing the references to it's &lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt; partition in &lt;tt class="docutils literal"&gt;/etc/fstab&lt;/tt&gt;. I have
good nightly backups of the system and smartctl was reporting that the
remaining drive was running fine. The system is pretty much read-only so
nightly backups were sufficient to provide a good restore point in case the
final drive failed.&lt;/p&gt;
&lt;p&gt;The replacement plan was to hook up the 2 new drives, which
use SATA instead of IDE, add them to the existing array and let
mdraid sync the data over from the old drive. At that point I would
have 3 drives in the array, all with 40G partitions. I would then
remove the old drive and grow the filesystem on the new drives to
take up all 500GB. Sometimes plans actually do work. The old drives
were EIDE and I had 2 SATA ports on the motherboard -- confirmed by
using &lt;tt class="docutils literal"&gt;dmidecode&lt;/tt&gt; to grab the motherboard's model number to look
it up online. The only glitch there was that I had to enable the
SATA controller in BIOS before the drives were recognized. I used
&lt;tt class="docutils literal"&gt;parted&lt;/tt&gt; to partition the drives into 3 partitions. They look
like this when finished:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[root&amp;#64;cat ~]# parted /dev/sda print
Model: ATA ST3500418AS (scsi)
Disk /dev/sda: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size   Type     File system     Flags
 1      1049kB  1000MB  999MB  primary  ext4            boot, raid
 2      1000MB  2000MB  999MB  primary  linux-swap(v1)
 3      2000MB  500GB   498GB  primary                  raid
&lt;/pre&gt;
&lt;p&gt;Don't forget to set the boot flag on the &lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt; partition on
&lt;strong&gt;both&lt;/strong&gt; drives. You never can tell when the BIOS might decide to
boot the other one, and if one fails you want the other to still be
bootable. GRUB can boot from a RAID partition as long as it is a
filesystem it supports, like ext2,3,4 and as long as mdraid
metadata v1,0 or earlier is used. This is because the metadata is
written to the end of the partition so grub never sees it. In v1.1
and later the RAID metadata is written to the start of the
partition and grub cannot find the filesystem. I setup &lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt; as
a 2 disk RAID1 like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
mdadm --create --verbose /dev/md1 --level=raid1 --raid-devices=2 --metadata=1.0 /dev/sdb1 /dev/sdc1
&lt;/pre&gt;
&lt;p&gt;I then copied over the &lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt; partition from the existing
system:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
mkfs.ext4 /dev/md1
mount /dev/md1 /mnt
rsync -avc /boot /mnt
umount /mnt
&lt;/pre&gt;
&lt;p&gt;Next is adding the new large partitions to the existing array. I
physically removed the failed drive so that it couldn't cause any
problems and added the new partitions like so:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[root&amp;#64;cat ~]# mdadm --manage /dev/md0 --add /dev/sdb3
mdadm: added /dev/sdb3
[root&amp;#64;cat ~]# mdadm --manage /dev/md0 --add /dev/sdc3
mdadm: added /dev/sdc3
&lt;/pre&gt;
&lt;p&gt;mdraid immediately begins to sync the data from the 40GB drive over
to one of the new drives. Since it is a 2 drive array it leaves the
other partition as a spare. There is no need to create a filesystem
on the new partitions because they are being written with the data
from the old drive, which includes the filesystem. &lt;tt class="docutils literal"&gt;/proc/mdstat&lt;/tt&gt;
looked like this during the sync:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[root&amp;#64;cat ~]# cat /proc/mdstat
Personalities : [raid1]
md1 : active raid1 sdc1[1] sdb1[0]
      975860 blocks super 1.0 [2/2] [UU]

md0 : active raid1 sdc3[3](S) sdb3[2] sda3[0]
      37458876 blocks super 1.1 [2/1] [U_]
      [&amp;gt;....................]  recovery =  0.6% (247296/37458876) finish=22.5min speed=27477K/sec
      bitmap: 1/1 pages [4KB], 65536KB chunk

unused devices:
&lt;/pre&gt;
&lt;p&gt;When that sync is finished I then manually failed the old 40GB drive - &lt;tt class="docutils literal"&gt;mdadm
&lt;span class="pre"&gt;--manage&lt;/span&gt; /dev/md0 &lt;span class="pre"&gt;--fail&lt;/span&gt; /dev/sda3&lt;/tt&gt; and waited for the data to be synched to
the other new drive and then removed the old drive from the array with this:
&lt;tt class="docutils literal"&gt;mdadm &lt;span class="pre"&gt;--manage&lt;/span&gt; /dev/md0 &lt;span class="pre"&gt;--remove&lt;/span&gt; /dev/sda3&lt;/tt&gt;. At this point I now have 40GB
of a 498GB partition being used. It would have worked just fine like that, but
it does seem like such a waste so I want to resize it. But first I made sure I
could boot the system with just the 2 new drives and their RAID1 &lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt;
partition.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;That's when I goofed.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I had grabbed the UUID values (unique values that help Linux find the right
partition to mount) and updated my &lt;tt class="docutils literal"&gt;/etc/fstab&lt;/tt&gt; with the new values. I also
updated the swap entries with their new UUID values (printed when you run
mkswap). You can always see the UUID of a partition by running &lt;tt class="docutils literal"&gt;blkid
/dev/sdX&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;blkid /dev/md0&lt;/tt&gt;. We used to refer to the drives in
&lt;tt class="docutils literal"&gt;/etc/fstab&lt;/tt&gt; using their device names, like /dev/sda1, but changes in how
drives are mounted means that they may not always get the same letter
assignment. The UUID is unique and tied to the filesystem so you are guaranteed
to always get what you expect. No more nasty surprises when you plug in a USB
drive and reboot only to find the BIOS changed the drive order on you.&lt;/p&gt;
&lt;p&gt;Oh, back to the goof. Well, in my excitement to see if GRUB really would boot
the RAID1 &lt;tt class="docutils literal"&gt;/boot&lt;/tt&gt; partition I had neglected to actually write GRUB to the MBR
of the new drives. This caused the system to, well, not boot. The fix was
simple, slap the old 40GB drive in, use its MBR to boot and then write GRUB
using grub:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[root&amp;#64;cat ~]# grub
root (hd0,0)
setup (hd1)
root (hd0,0)
setup (hd2)
&lt;/pre&gt;
&lt;p&gt;The root line should match what is in /etc/grub.conf and the setup (hdX) tells
it to write to that drive, which may be a different number when booting without
the old drive installed.&lt;/p&gt;
&lt;p&gt;Next is resizing things. You need to resize the RAID container and then resize
the filesystem. The first time I tried this I ran into the &lt;tt class="docutils literal"&gt;Bitmap must be
removed before size can be changed&lt;/tt&gt; error which sounds a bit ominous when you
aren't expecting it. What it means is that the bitmap that the array uses to
track what has been synced needs to be removed. It isn't big enough for the new
size anyway. To do that you run &lt;tt class="docutils literal"&gt;mdadm &lt;span class="pre"&gt;--grow&lt;/span&gt; /dev/md0 &lt;span class="pre"&gt;--bitmap&lt;/span&gt; none&lt;/tt&gt; which
allows you to then actually grow it - &lt;tt class="docutils literal"&gt;mdadm &lt;span class="pre"&gt;--grow&lt;/span&gt; /dev/md0 &lt;span class="pre"&gt;--size&lt;/span&gt; max&lt;/tt&gt;.
This will take a while. How long it takes depends on, things like drive
controller speed, CPU speed, drive speed and who knows what else. In my case it
took about 3 hours. You can monitor the progress by watching &lt;tt class="docutils literal"&gt;/proc/mdstat&lt;/tt&gt;
using &lt;tt class="docutils literal"&gt;watch &lt;span class="pre"&gt;-n&lt;/span&gt; 20 cat /proc/mdstat&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;When that is finished you want to add the bitmap back to the array, which is
done by running &lt;tt class="docutils literal"&gt;mdadm &lt;span class="pre"&gt;--grow&lt;/span&gt; /dev/md0 &lt;span class="pre"&gt;--bitmap&lt;/span&gt; internal&lt;/tt&gt;. Now we are ready
to resize the filesystem. Back in the old days (cough) you had to reboot into a
rescue disk and run things like this on an unmounted filesystem. Those days are
long gone. We just need to run &lt;tt class="docutils literal"&gt;resize2fs /dev/md0&lt;/tt&gt; and sit back and watch it
grow. You can monitor with all the normal filesystem utilities. It shows the
new size in realtime - &lt;tt class="docutils literal"&gt;df &lt;span class="pre"&gt;-h&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The last step, as it should be with any filesystem changes, is to run a
filesystem check. &lt;tt class="docutils literal"&gt;touch /forcefsck&lt;/tt&gt; and reboot and it will be handled at
boot time.&lt;/p&gt;
&lt;p&gt;I have to thank the many resources found via google, but especially &lt;a class="reference external" href="http://www.howtoforge.com/replacing_hard_disks_in_a_raid1_array"&gt;this howto
forge article on replacing disks in a RAID1 array&lt;/a&gt;, and the
&lt;a class="reference external" href="https://raid.wiki.kernel.org/index.php/Growing"&gt;kernel.org wiki entry on Growing a RAID&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;(note: this is what worked for me, in my setup, yours will be
different and this information may or may not work for you. Make
sure you have good backups before doing anything with your
filesystems).&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; I think my original title was dumb. I've changed it.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 04 Nov 2010 22:21:00 -0000</pubDate><category>Fedora</category><category>Linux</category><category>RAID</category><category>Backup</category></item><item><title>Fedora Pumpkin</title><link>http://brianlane.com/fedora-pumpkin.html</link><description>&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/lane-family/5130087822/"&gt;&lt;img alt="http://farm2.static.flickr.com/1097/5130087822_bb8aa69cec.jpg" src="http://farm2.static.flickr.com/1097/5130087822_bb8aa69cec.jpg" /&gt;&lt;/a&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/lane-family/5130072550/"&gt;&lt;img alt="http://farm5.static.flickr.com/4041/5130072550_d8e8146575.jpg" src="http://farm5.static.flickr.com/4041/5130072550_d8e8146575.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;I used the template from
&lt;a class="reference external" href="http://www.flickr.com/photos/redhatmagazine/1525238697/"&gt;here&lt;/a&gt;.
There is also a template for
&lt;a class="reference external" href="http://www.flickr.com/photos/redhatmagazine/1526300718/"&gt;Shadowman here&lt;/a&gt;.
Maybe I'll try that one next year.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 31 Oct 2010 10:44:00 -0000</pubDate><category>Fedora</category><category>Halloween</category><category>Pumpkin</category></item><item><title>Kindle on Linux using Wine</title><link>http://brianlane.com/kindle-on-linux-using-wine.html</link><description>&lt;p&gt;I have a few books I've bought for reading using the Kindle app on my iPhone.
I'd like to be able to read them on my &lt;a class="reference external" href="http://www.fedoraproject.org"&gt;Fedora Linux&lt;/a&gt; based MacBook as well, but Amazon hasn't
released a version for Linux yet, which is ironic given that the Kindle's OS is
Linux based. All is not lost, there is an excellent project called &lt;a class="reference external" href="http://www.winehq.org/"&gt;Wine&lt;/a&gt; that enables you to run many Windows applications on
your Linux system. My experience with it has been mixed, with some applications
working fine and others not making it past the installer stage.&lt;/p&gt;
&lt;p&gt;The trick to get this to work is to use the Beta version of the Kindle for PC
app. Specifically this version - 'Kindle App v1.0 Beta 1 (25338)' The sha256sum
for the .exe is
83f1190a7f4a914921d17546d6fe8f9ba609275b4af0fa5619398b87643a2779 and it is
currently available &lt;a class="reference external" href="http://www.mediafire.com/?l5c3ozmtvdebmrf"&gt;from here&lt;/a&gt; as
a .tar file (the .exe is inside the .tar).&lt;/p&gt;
&lt;p&gt;My setup is pretty simple, install Wine from the Fedora repository and make
sure SELinux is set to permissive. I do enough different stuff on this machine
that leaving SELinux enabled always ends up causing more trouble than it's
worth. Download the Kindle app installer and double click on the .exe, this
will run the installer and prompt you to enter your Amazon login info. It will
create a launcher icon on your desktop for easy access. That's all there is to
it!&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a class="reference external" href="http://scienceblogs.com/gregladen/2010/04/how_to_actuall_get_the_kindle.php"&gt;Greg Laden&lt;/a&gt;
for his post on how to get this working. With Fedora 13 I didn't need to set it
to run as Windows 98, leaving the defaults worked fine.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 18 Sep 2010 09:42:00 -0000</pubDate><category>Books</category><category>Fedora</category><category>Linux</category><category>Kindle</category></item><item><title>tidy_html plugin for rawdog</title><link>http://brianlane.com/tidy_html-plugin-for-rawdog.html</link><description>&lt;p&gt;Requires python-tiny package on Fedora. Cleans up the HTML,
preventing broken elements from spilling over into adjacent
postings. Code was lifted from feedparser.py and dropped into a
plugin for rawdog since I couldn't find an easy way to get mx.Tiny
installed.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# rawdog plugin to tidy up html output using python-tidy module&lt;/span&gt;
&lt;span class="c"&gt;# Brian C. Lane &amp;lt;bcl@brianlane.com&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tidy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parseString&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;rawdoglib.plugins&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tidy_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;baseurl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="n"&gt;utf8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_xhtml&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numeric_entities&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;lt;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;lt;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;lt;/body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;lt;/body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;rawdoglib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attach_hook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;clean_html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tidy_html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 29 Aug 2010 16:04:00 -0000</pubDate><category>Python</category></item><item><title>Sharing Music on the LAN</title><link>http://brianlane.com/sharing-music-on-the-lan.html</link><description>&lt;p&gt;No, not on the lam. On the LAN. I have a fairly large collection of
music. Years ago I used iTunes to rip the CD's to AAC format.
Recently I've been using Amazon.com for more of my downloads so I
have converted the library to high quality VBR mp3 files instead. I
like being able to play the music no matter which system I am
using, and the iTunes sharing works well for that. I wanted to
centralize storage of the files, and setup sharing from one of my
Fedora 13 systems so I went in search of a solution. There are
several out there, but I think I hit on the simplest of them.&lt;/p&gt;
&lt;p&gt;iTunes (and several other music playing apps like Rhythmbox) use
the DAAP protocol for sharing music between systems. On fedora this
can be provided by the mt-daapd package (check your distribution
for it, I'll bet it is included). Setup was dead easy:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Install mt-daapd package&lt;/li&gt;
&lt;li&gt;Open up port 3689 on your firewall (I edit
/etc/sysconfig/iptables)&lt;/li&gt;
&lt;li&gt;Edit /etc/mt-daapd.conf and point it to the top directory of
your music storage, don't forget to change the admin password for
the web interface&lt;/li&gt;
&lt;li&gt;run chkconfig mtdaapd on; service mtdaapd start&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You should now be able to connect to the share using Rhythmbox or
similar DAAP supporting players. It is even nicer if your system
announces itself. This can be accomplished by adding the following
service definition to the avahi open source Bonjour daemon:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; standalone=’no’?&amp;gt;
&amp;lt;!DOCTYPE service-group SYSTEM &amp;quot;avahi-service.dtd&amp;quot;&amp;gt;
&amp;lt;service-group&amp;gt;
    &amp;lt;name replace-wildcards=&amp;quot;yes&amp;quot;&amp;gt;%h&amp;lt;/name&amp;gt;
    &amp;lt;service&amp;gt;
        &amp;lt;type&amp;gt;\_daap.\_tcp&amp;lt;/type&amp;gt;
        &amp;lt;port&amp;gt;3689&amp;lt;/port&amp;gt;
        &amp;lt;txt-record&amp;gt;txtvers=1&amp;lt;/txt-record&amp;gt;
        &amp;lt;txt-record&amp;gt;iTSh Version=131073&amp;lt;/txt-record&amp;gt;
        &amp;lt;txt-record&amp;gt;Version=196610&amp;lt;/txt-record&amp;gt;
    &amp;lt;/service&amp;gt;
&amp;lt;/service-group&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Copy this into /etc/avahi/services/mt-daapd.service and run service
avahi-daemon restart. Now your share should appear in applications like iTunes
which use Bonjour to discover local DAAP services.&lt;/p&gt;
&lt;p&gt;The last piece of this is downloading purchased mp3 files from Amazon. This is
easily accomplished by installing the clamz package. After installing, visit
&lt;a class="reference external" href="http://www.amazon.com/gp/dmusic/after_download_manager_install.html"&gt;http://www.amazon.com/gp/dmusic/after_download_manager_install.html&lt;/a&gt;, to
activate the browser cookie. Then, when you purchase an mp3 or an mp3 album
Fire Fox will prompt you to run clamz, which then downloads the files for you.
Thanks to &lt;a class="reference external" href="http://www.vleeuwen.net/tag/firefly"&gt;Dirk-Jan's page&lt;/a&gt; for info on
setting up avahi, and to to &lt;a class="reference external" href="http://www.mjmwired.net/resources/mjm-fedora-f13.html"&gt;Mauriat Miranda's page&lt;/a&gt; for help in setting
up mp3 playback.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 15 Aug 2010 15:19:00 -0000</pubDate><category>Linux</category><category>Fedora</category></item><item><title>Home Media Server Updates</title><link>http://brianlane.com/home-media-server-updates.html</link><description>&lt;p&gt;Tonight I finished adding delete handlers and a delete confirmation dialog to
&lt;a class="reference external" href="http://github.com/bcl/HMS"&gt;HMS&lt;/a&gt;. This is probably the state that the code
will be in for my &lt;a class="reference external" href="http://linuxfestnorthwest.org/sessions/roku-python-local-media-player"&gt;LFNW presentation&lt;/a&gt; next
Saturday.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 17 Apr 2010 22:26:00 -0000</pubDate><category>Python</category><category>HMS</category><category>Roku</category><category>Linuxfest Northwest</category></item><item><title>color output from git log -p on OSX</title><link>http://brianlane.com/color-output-from-git-log-p-on-osx.html</link><description>&lt;p&gt;By default git on OSX wasn't colorizing its output. Two things
needed to be setup - setting the color.ui to auto and setting the
pager (less) to allow raw characters. Add this to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.gitconfig&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;[color]&lt;/span&gt;
&lt;span class="na"&gt;ui&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;auto&lt;/span&gt;
&lt;span class="k"&gt;[core]&lt;/span&gt;
&lt;span class="na"&gt;pager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;less -R&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Presto! Nice colorized output from git!&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 17 Apr 2010 22:20:00 -0000</pubDate><category>git</category><category>OSX</category></item><item><title>Fixed live.aisparser.com</title><link>http://brianlane.com/fixed-liveaisparsercom.html</link><description>&lt;p&gt;I wasn't escaping the ship name and destination before creating the
XML so a &amp;amp; character would make the javascript choke. Fixed now, so
you should be &lt;a class="reference external" href="http://live.aisparser.com"&gt;seeing ships update&lt;/a&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Mon, 05 Apr 2010 18:09:00 -0000</pubDate><category>AIS</category></item><item><title>GUETech is back up</title><link>http://brianlane.com/guetech-is-back-up.html</link><description>&lt;p&gt;&lt;a class="reference external" href="http://www.guetech.org"&gt;www.guetech.org&lt;/a&gt; was the first domain I
ever registered. This was back when domains were free and you send
in an email form with your request. I used it for a UUCP connected
BBS (via &lt;a class="reference external" href="http://www.eskimo.com"&gt;Eskimo North&lt;/a&gt; for a short time
from my apartment in the mid 90s. Since then I have mostly used it
to host mirrors of the
&lt;a class="reference external" href="http://gallery.guetech.org"&gt;Infocom Gallery&lt;/a&gt; project and the
&lt;a class="reference external" href="http://if-archive.guetech.org"&gt;Interactive Fiction Archive&lt;/a&gt;. I
have just finished moving the data to a new server, and in addition
to ftp access to the archive I am now offering http access. Due to
an accident (me not making sure all my domains were setup properly)
the guetech.org website has been down since last August.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 03 Apr 2010 06:23:00 -0000</pubDate><category>GUETech</category><category>Interactive Fiction</category></item><item><title>Newseum Page Grabber Script</title><link>http://brianlane.com/newseum-page-grabber-script.html</link><description>&lt;p&gt;&lt;a class="reference external" href="http://www.newseum.org/todaysfrontpages/default.asp"&gt;Newseum&lt;/a&gt;
archives the front pages of of over 500 newspapers from all around
the world. If you know the ID of the papers you want to see you can
use this simple &lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt; program to
download the jpg of the papers' front page to your local system.
Edit the CITIES list to set the IDs of the papers to be grabbed.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    Quick Newseum Frontpage Grabber script&lt;/span&gt;
&lt;span class="sd"&gt;    Copyright 2009 by Brian C. Lane&lt;/span&gt;
&lt;span class="sd"&gt;    Imp Software&lt;/span&gt;
&lt;span class="sd"&gt;    All Rights Reserved&lt;/span&gt;

&lt;span class="sd"&gt;    Modify CITIES list below to add the city designators (as seen in the&lt;/span&gt;
&lt;span class="sd"&gt;    URLS at http://www.newseum.org/todaysfrontpages/default.asp)&lt;/span&gt;
&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;urllib2&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;urlparse&lt;/span&gt;

&lt;span class="c"&gt;# Add more cities here&lt;/span&gt;
&lt;span class="n"&gt;CITIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;AL_AS&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;AL_MA&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;NEWSEUM_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.newseum.org/todaysfrontpages/hr.asp?fpVname=&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;NEWSEUM_IMG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.newseum.org&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetchNewseumImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    Fetch the image for a city&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Parsing the page for &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NEWSEUM_URL&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;# Quick and dirty grep for the image name&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;lt;img class=&amp;quot;tfp_lrg_img&amp;quot; src=&amp;quot;(.*)&amp;quot; alt=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;img_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NEWSEUM_IMG&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Saving the image for &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;wb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    Main code goes here&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;CITIES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fetchNewseumImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The source is also hosted
&lt;a class="reference external" href="http://github.com/coderpunk/Newseum-Pages"&gt;here at github&lt;/a&gt;&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 07 Feb 2010 09:08:00 -0000</pubDate><category>Python</category></item><item><title>ALMS Countdown Approved in Record Time</title><link>http://brianlane.com/alms-countdown-approved-in-record-time.html</link><description>&lt;p&gt;Much to my surprise my 2 new iPhone apps were approved today. This must be a
new record for the App Revew process -- according to the history the &lt;a class="reference external" href="http://itunes.apple.com/us/app/alms-countdown/id353440928?mt=8"&gt;American
Le Mans Series (ALMS) Countdown app&lt;/a&gt; started
review at 11:26 AM and was approved at 15:08 (3h42m), the &lt;a class="reference external" href="http://itunes.apple.com/us/app/nascar-countdown/id353416229?mt=8"&gt;NASCAR Countdown
version&lt;/a&gt;
took slightly longer, from 9:23 to 16:42 (7h19m). I suppose the fact that these
are dead-simple apps with only 2 views may have had something to do with the
fast turn around. But with the first &lt;a class="reference external" href="http://www.nascar.com"&gt;NASCAR&lt;/a&gt; race of
the season only 3 days away I'm pretty happy!&lt;/p&gt;
&lt;img alt="/images/nascar-iphone/Screenshot-2010.01.30-20.15.47.png" src="/images/nascar-iphone/Screenshot-2010.01.30-20.15.47.png" /&gt;
&lt;img alt="/images/alms/Screenshot-2010.01.31-17.41.41.png" src="/images/alms/Screenshot-2010.01.31-17.41.41.png" /&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Tue, 02 Feb 2010 21:37:00 -0000</pubDate><category>ALMS</category><category>iPhone</category><category>NASCAR</category><category>Racing</category></item><item><title>ALMS Countdown for iPhone</title><link>http://brianlane.com/alms-iphone.html</link><description>&lt;p&gt;The ALMS Countdown app displays a countdown to the next &lt;a class="reference external" href="http://www.americanlemans.com/"&gt;American Le Mans Series&lt;/a&gt; race, the name of the race and the television network carrying the race.
On the flip side all of the races for the 2010 season are listed, and tapping on one of them will go to the website for that track.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;iPhone or iPod&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;em&gt;v1.0&lt;/em&gt; Initial release&lt;/dd&gt;
&lt;/dl&gt;
&lt;a class="reference external image-reference" href="http://itunes.apple.com/us/app/alms-countdown/id353440928?mt=8"&gt;&lt;img alt="images/misc/appstore.png" class="align-center" src="images/misc/appstore.png" /&gt;&lt;/a&gt;
&lt;div class="section" id="screenshots"&gt;
&lt;h2&gt;Screenshots&lt;/h2&gt;
&lt;img alt="images/alms/Screenshot-2010.01.31-17.41.41.png" class="align-center" src="images/alms/Screenshot-2010.01.31-17.41.41.png" /&gt;
&lt;img alt="images/alms/Screenshot-2010.01.31-17.41.50.png" class="align-center" src="images/alms/Screenshot-2010.01.31-17.41.50.png" /&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Tue, 02 Feb 2010 00:00:00 -0000</pubDate><category>ALMS</category><category>iPhone</category></item><item><title>Submitted NASCAR Countdown app to App Store</title><link>http://brianlane.com/submitted-nascar-countdown-app-to-app-store.html</link><description>&lt;p&gt;I have made an &lt;a class="reference external" href="nascar-countdown-for-iphone.html"&gt;iPhone version&lt;/a&gt;
of my &lt;a class="reference external" href="nascar-countdown-dashboard-widget.html"&gt;NASCAR Countdown Widget&lt;/a&gt; and
sumbitted it to the App Store. The NASCAR Countdown app displays a countdown to
the next race, the name of the race and the television network carrying the
race. On the flip side all of the races for the 2010 season are listed, and
tapping on one of them will go to the nascar.com website for that track.&lt;/p&gt;
&lt;img alt="/images/nascar-iphone/Screenshot-2010.01.30-20.15.47.png" src="/images/nascar-iphone/Screenshot-2010.01.30-20.15.47.png" /&gt;
&lt;img alt="/images/nascar-iphone/Screenshot-2010.01.30-20.15.57.png" src="/images/nascar-iphone/Screenshot-2010.01.30-20.15.57.png" /&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 31 Jan 2010 10:48:00 -0000</pubDate><category>iPhone</category></item><item><title>Hygrosens Python Library</title><link>http://brianlane.com/hygrosens.html</link><description>&lt;p&gt;&lt;a class="reference external" href="http://www.hygrosens.com"&gt;Hygrosens&lt;/a&gt; manufactures a number of sensors for measuring temperature,
humidity, light level, pressure. Their devices use a common serial data format
for a wide variety of sensors, include 1-wire sensors from Dallas. This library
reads the output from Hygrosens devices and passes it to a calling function as
a hash. I have included an example that outputs the readings in human readable
format, and another that stores the readings into a MySQL database.&lt;/p&gt;
&lt;img alt="Humidity Sensor" src="images/hygrosens/183003.jpg" /&gt;
&lt;p&gt;Humidity/Temperature sensor&lt;/p&gt;
&lt;img alt="Weather Station" src="images/hygrosens/weatherstation.jpg" /&gt;
&lt;p&gt;Weather station with temperature, humidity (relative and absolute), light level
and pressure. The 9V battery adapter is my own modification for my 9V wall-wart
power supply.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Current Version&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/hygrosens/hygrosens-0.6.tar.bz2"&gt;Download v0.6 here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/hygrosens"&gt;Browse previous releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;&lt;strong&gt;Sample Output&lt;/strong&gt;&lt;/p&gt;
&lt;!-- Temperature    : 21.75C
Rel. Humidity  : 30.84%
Dew Point      : 3.81C
Abs. Humidity  : 5.90%
Light Level    : 12
Light Level    : 0
Light Level    : 0
Light Level    : 0
Pressure       : 100194.38 --&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;pyserial - available from &lt;a class="reference external" href="http://pyserial.sourceforge.net"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.hygrosens.com"&gt;Hygrosens&lt;/a&gt; hardware&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;em&gt;v0.5&lt;/em&gt; - Initial release with working class library and examples. Not
enough documentation has been written yet.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v0.6&lt;/em&gt; - Added weather.py example to graph the output from the weather
station using &lt;a class="reference external" href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/"&gt;RRDtool graphs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;&lt;strong&gt;Hygrosens Documents&lt;/strong&gt;
The Hygrosens website is all in German, which I don't read. Here are english
copies of some of their documentation&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/hygrosens/183003_HYTELOG_SMD_dbe.pdf"&gt;Humidity Sensor Module (plastic)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/hygrosens/183017_HYTELOG_ESF_dbe.pdf"&gt;Humidity Sensor Module (stainless)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/hygrosens/184010_TEMPLOG_DBE.pdf"&gt;Dallas DS1820 Temperature System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/hygrosens/Protokoll_V2_SRC_dbe.pdf"&gt;Serial Communications Protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/hygrosens/Wetterstation_Datenformat.doc"&gt;Weather Station Documentation&lt;/a&gt; (German)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/hygrosens/SerialFormat.doc"&gt;Serial format documentation&lt;/a&gt; (German)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 31 Jan 2010 00:00:00 -0000</pubDate><category>hygrosens</category><category>python</category><category>1-wire</category></item><item><title>WZON T-Shirts</title><link>http://brianlane.com/wzon-t-shirts.html</link><description>&lt;p&gt;I'm not sure what made me think of these today, but I did a couple
of Google searches to see if I could track down any more of these
shirts. The only one I could find is the Creep shirt. There seems
to be a lack of info on them on the web, so I'm going to help fix
that. Stephen King owns a couple of radio stations in Maine, one is
WZON and back in the mid 80's the Stephen King newsletter had
advertisements for these t-shirts. As a loyal constant reader it
was my duty to buy them, and I think these were the only ones
offered. I wore these in rotation with my Bloom County t-shirts all
through high school. They're a little worn, but really in much
better shape than some of the shirts I have from places like Cafe
Press.&lt;/p&gt;
&lt;img alt="WZON Creep Shirt (Front)" src="images/wzon/DSC_0009.JPG" /&gt;
&lt;img alt="WZON Creep Shirt (Back)" src="images/wzon/DSC_0010.JPG" /&gt;
&lt;img alt="WZON Skull (Front)" src="images/wzon/DSC_0011.JPG" /&gt;
&lt;img alt="WZON Skull (Back)" src="images/wzon/DSC_0012.JPG" /&gt;
&lt;img alt="WZON Shirt" src="images/wzon/DSC_0013.JPG" /&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Wed, 27 Jan 2010 22:41:00 -0000</pubDate><category>Stephen King</category><category>Shirts</category></item><item><title>NASCAR Countdown Widget Updated for 2010</title><link>http://brianlane.com/nascar-countdown-widget-updated-for-2010.html</link><description>&lt;p&gt;I have just updated my
&lt;a class="reference external" href="nascar-countdown-dashboard-widget.html"&gt;NASCAR Dashboard Widget&lt;/a&gt;
for the 2010 season. All race time and channels should now be
current.&lt;/p&gt;
&lt;img alt="/images/nascar/Screen-shot-2010-01-19-at-8.16.47-AM.png" src="/images/nascar/Screen-shot-2010-01-19-at-8.16.47-AM.png" /&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Tue, 19 Jan 2010 08:26:00 -0000</pubDate><category>OSX</category><category>NASCAR</category></item><item><title>NASCAR Countdown Dashboard Widget</title><link>http://brianlane.com/nascar.html</link><description>&lt;iframe src="downloads/nascar/Daytona.html" width="679" height="46" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;p&gt;This is a simple countdown widget for the OSX Dashboard. It is a pure javascript
implementation so it will also run inside a web browser as you can see above.&lt;/p&gt;
&lt;p&gt;This widget will display the time until the next &lt;a class="reference external" href="http://www.nascar.com/races/cup/2009/data/schedule.html"&gt;NASCAR Broadcast&lt;/a&gt;, the countdown
takes into account your local timezone.&lt;/p&gt;
&lt;p&gt;This widget was inspired by the &lt;a class="reference external" href="http://www.dark-hawk.de/Downloads.html"&gt;Sprint Cup Widget&lt;/a&gt;
which is now outdated. I used the graphics for the Daytona countdown from
&lt;a class="reference external" href="http://www.nascar.com"&gt;NASCAR&lt;/a&gt; and modified it to calculate the correct time and select the next
available race.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1/19/2010&lt;/strong&gt; Updated the schedule for the 2010 season&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Current Version&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/nascar/NASCAR-2010.zip"&gt;Download v2.0 here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="static/downloads/nascar/"&gt;Browse previous releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;OSX or Javascript&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes:&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;em&gt;v2.0&lt;/em&gt; Updated for 2010 season&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v1.0&lt;/em&gt; Initial release&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Tue, 19 Jan 2010 00:00:00 -0000</pubDate><category>OSX</category><category>NASCAR</category><category>Desktop Widget</category></item><item><title>Simple SQL Schema Migration</title><link>http://brianlane.com/simple-sql-schema-migration.html</link><description>&lt;p&gt;I'm working on an application to manage my streaming media for my
&lt;a class="reference external" href="http://www.roku.com"&gt;Roku&lt;/a&gt; player using
&lt;a class="reference external" href="http://www.sqlite.org"&gt;sqlite3&lt;/a&gt; and
&lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt; for everything. One thing I've
learned over the years is that your SQL schema always changes. Once
your code is in production you always have something you need to
change about it, whether it's adding a new column, changing a type
or tables to support new features. I wanted a way to automatically
update the database schema when a new version of the code is
installed. I don't want to jump into the complexity of using
&lt;a class="reference external" href="http://www.sqlalchemy.org/"&gt;SQLAlchemy&lt;/a&gt; and
&lt;a class="reference external" href="http://code.google.com/p/sqlalchemy-migrate/"&gt;migrate&lt;/a&gt; so I came
up with this simple method. The database has a table named schema
with a single row with the current schema version in it. This class
checks the current version and executes any missing commands,
bringing it up to the latest version.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DbSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    Database schema creation and modification&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class="c"&gt;# Schema revisions, rev[0], etc. is a list of SQL operations to run to&lt;/span&gt;
    &lt;span class="c"&gt;# bring the database up to date.&lt;/span&gt;
    &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&amp;quot;  create table users(id INTEGER PRIMARY KEY, username UNIQUE, password, email);&lt;/span&gt;
&lt;span class="s"&gt;                create table sources(id INTEGER PRIMARY KEY, name, type, path UNIQUE);&lt;/span&gt;

&lt;span class="s"&gt;                create table schema(version);&lt;/span&gt;
&lt;span class="s"&gt;                insert into schema(version) values(1);&lt;/span&gt;
&lt;span class="s"&gt;            &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="c"&gt;# Add default values&lt;/span&gt;
            &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; insert into users(username, password) values(&amp;quot;admin&amp;quot;,&amp;quot;badpassword&amp;quot;);&lt;/span&gt;

&lt;span class="sd"&gt;                update schema set version=2;&lt;/span&gt;
&lt;span class="sd"&gt;            &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="c"&gt;# Add media table&lt;/span&gt;
            &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; create table media(&lt;/span&gt;
&lt;span class="sd"&gt;                    id INTEGER PRIMARY KEY,&lt;/span&gt;
&lt;span class="sd"&gt;                    name,&lt;/span&gt;
&lt;span class="sd"&gt;                    path&lt;/span&gt;
&lt;span class="sd"&gt;                );&lt;/span&gt;

&lt;span class="sd"&gt;                update schema set version=3;&lt;/span&gt;
&lt;span class="sd"&gt;            &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;        Upgrade the database to the current schema version&lt;/span&gt;
&lt;span class="sd"&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class="c"&gt;# Get the current schema version number&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row_factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;
        &lt;span class="n"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;select version from schema&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:]:&lt;/span&gt;
                &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executescript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Initialize it with the path to your database, and then call the
upgrade() method on it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DbSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;./library.db&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add new tables, changes to old tables, default data, etc. to new strings in
the sql list. Make sure to update the schema table's version as the last step
for each revision. As long as you only make database changes via this class you
will ensure that the tables are ready for your new code when each new revision
is released. This version is being used with sqlite3, but works just as well
with mysql or postgresql.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 10 Jan 2010 12:57:00 -0000</pubDate><category>Programming</category><category>Python</category><category>SQL</category></item><item><title>Moved the blog home</title><link>http://brianlane.com/moved-the-blog-home.html</link><description>&lt;p&gt;I decided to move the blog from Wordpress hosting back to my own
server. I want to be able to run my own Google Ads on the system
and Wordpress doesn't allow that. I used the Export/Import feature
of Wordpress 2.9 and found that it misses a couple of things. It
doesn't transfer the theme over, the widets or the links. I had to
handle all of them manually. Otherwise the move has gone smoothly.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 27 Dec 2009 19:45:00 -0000</pubDate><category>Wordpress</category><category>Blog</category></item><item><title>Streaming Local Video With Your Roku</title><link>http://brianlane.com/streaming-local-video-with-your-roku.html</link><description>&lt;p&gt;Ever since I switched from Dish Network to a &lt;a class="reference external" href="http://www.roku.com"&gt;Roku&lt;/a&gt;
player a few months ago I have had a couple of things I wanted my player to be
able to do. The ability to categorize my &lt;a class="reference external" href="http://www.netflix.com"&gt;Netflix&lt;/a&gt;
queue is at the top of my list and it would be very cool to be able to play
video from a local server. The SDK won't help me modify the Netflix
application, but streaming from a local source is actually not a huge problem.&lt;/p&gt;
&lt;p&gt;On Friday Roku finally released the SDK for their handy little Roku Video
player (sometimes called a Netflix box since that was originally the only
content you could stream). The SDK is free, all you have to do is signup at the
&lt;a class="reference external" href="http://www.roku.com/developer"&gt;developer page&lt;/a&gt;. The zip archive contains
everything you need to get started hacking together a new channel for your Roku
player.&lt;/p&gt;
&lt;p&gt;For the most part development is cross platform. You are restricted to using
their language, BrightScript, so there are no compilers or IDE needed. It helps
if you have the make utility available on your system, the examples come with
makefiles that will zip up the application and install it into your player with
a single command. If you want nice images to show up while scanning through a
video you will need to capture them from the file and create a BIF file to tell
the player when to show the images. The biftool is currently only available on
linux and Windows.&lt;/p&gt;
&lt;p&gt;To be able to upload software to your player you need to enable developer mode.
This is accomplished with a set of remote control keypresses. For some reason
it took me about 10 tries before I got it to work. I'm still not sure if it
depends on where you start from, but what finally worked for me was being at
the top level channel menu with something other than settings selected.&lt;/p&gt;
&lt;p&gt;Once that is done the box now has a simple server running on port 80 and a
debug port on 8085 where you can view debug output from your app or from the
system if the upload failed, or if parsing the script files failed. That's all
there is to it. No cumbersome app signing needed at this point. It makes it
very easy to edit, upload, try, debug, repeat. If you want to actually publish
your application as a new channel for the world to use the process is more
involved and requires Roku to approve your application.&lt;/p&gt;
&lt;p&gt;The SDK includes, among other things, a couple of video examples. One simply
points to a URL and plays it (the URL is hard-coded into the application). The
other is more fully featured and uses TED talk videos. It allows you to setup a
hierarchy of categories using a couple of XML files. This is a good place to
start for streaming local content.&lt;/p&gt;
&lt;p&gt;The first thing I did was setup an Apache 2.2.13 server on my son's Fedora11
system. I simply aliased the directory of mp4 videos and it was up and running.
As a side note, Chrome (at least on OSX) can stream mp4 videos over http
without installing anything else.&lt;/p&gt;
&lt;p&gt;I then played around with the simple stream example to make sure I could
actually watch the videos. They were encoded using Handbrake on either a OSX or
Fedora system. Most are 1G in size or less, and I left most of the encode
settings alone. I found that about the first hour streams fine, but after that
point the player starts to rebuffer every minute or so. It appears to depend on
the location in the file, so it may have something to do with how it was
encoded.&lt;/p&gt;
&lt;p&gt;The documentation included appears to be fairly complete. The have extensive
documentation on BrightScript, and on the Roku extensions that you use to
access to features of the player. I did find a couple of things that weren't
described in detail, but at this point that hasn't hindered progress at all.
BrightScript is a fairly simple language and anyone with programming experience
should have no trouble catching on quickly.&lt;/p&gt;
&lt;p&gt;The example video app uses a hard-coded URL for the source of the XML driving
it. I added a keyboard page that prompts the user to enter the host or IP
address of their video server. It saves this to the registry (persistent
storage) so it only needs to be entered once. For the moment, this is really
the only change I needed to make to the example application. Everything else
happens on the server side.&lt;/p&gt;
&lt;p&gt;I slapped together a Python script to take the names of my mp4 videos and
generate the feed XML to drive the player. I used mp4info to pull the video's
bitrate and format from the file and insert into the movie's description page.
I don't have cover art for them, so that got hard-coded to a default image. The
script generates a static XML file for the Roku to load when my custom
application is run.&lt;/p&gt;
&lt;p&gt;At this point I can browse the movies and play them. Mostly. I've run into a
couple of glitches, and am not sure exactly what the solution for them is yet.
One is that it seems that at about the 1 hour point in the video playback it
starts to rebuffer every minute or two. If I stop playback, restart and skip to
the 1 hour marks it still happens, so it appears to depend on the point in the
file, not the time spent playing.&lt;/p&gt;
&lt;p&gt;The other is that the aspect ratio of many of the videos isn't quite right. All
of them seem to be squished to some degree or another. This is probably due to
the Handbrake parameters I used when encoding them from the original DVDs. They
look fine when played back on a PC but the Roku either isn't properly sizing
them, or I'm doing something wrong (more than likely).&lt;/p&gt;
&lt;p&gt;Overall I am very happy with the Roku and the SDK. They have done an excellent
job of documenting the system, providing example code and especially keeping it
from turning into a brick. Several times I have managed to get it to lock up
and reset itself. It has always come right back up with no problems. I am
looking forward to seeing what other channels people come up with. On the top
of the list for me is Hulu streaming, but I'll leave that up to someone else to
implement.&lt;/p&gt;
&lt;p&gt;You can look at my code, for what its worth, at my &lt;a class="reference external" href="http://bitbucket.org/bcl/homevideo/"&gt;bitbucket homevideo
repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; This project morphed into the Home Media Server project, the code
for that can be found &lt;a class="reference external" href="http://github.com/bcl/HMS/"&gt;here on GitHub&lt;/a&gt;&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 20 Dec 2009 17:38:00 -0000</pubDate><category>Linux</category><category>Python</category><category>Roku</category><category>Streaming Video</category></item><item><title>SharePics Accepted by Apple!</title><link>http://brianlane.com/sharepics-accepted-by-apple.html</link><description>&lt;p&gt;After many
minutes of redesign the new look of SharePics was ready to go. I
re-packaged the app, captured new screenshots, and re-submitted it
to the AppStore. 9 days later I received an email notifying me that
my app was now available for sale
&lt;a class="reference external" href="http://itunes.apple.com/us/app/sharepics/id342123800?mt=8"&gt;in the App Store&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Thanks to everyone who offered advice and design ideas after the
crushing rejection last month. I couldn't have done it without you!
Now you can easily share your pictures with your friends (note, you
need an iPhone or iPod Touch with Bluetooth support and iPhone OS
v3.0 or later).&lt;/p&gt;
&lt;img alt="/images/sharepics/Screenshot-2009.12.05-14.31.03.png" src="/images/sharepics/Screenshot-2009.12.05-14.31.03.png" /&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 17 Dec 2009 22:15:00 -0000</pubDate><category>iPhone</category><category>Objective C</category></item><item><title>SharePics for iPhone</title><link>http://brianlane.com/sharepics.html</link><description>&lt;p&gt;SharePics is a simple application that uses Bluetooth to share pictures between
two iPhone or iPod Touch (2nd gen) devices. You can also take pictures using
the app and share them immediately. There is no need for a wireless access
point or even a 3G connection. You can select your pictures from the iPhone
album, or take a new photo with the camera and send it to your friend.&lt;/p&gt;
&lt;img alt="images/sharepics/Screenshot-2009.12.05-14.31.03.png" src="images/sharepics/Screenshot-2009.12.05-14.31.03.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.29.40.png" src="images/sharepics/Screenshot-2009.11.22-13.29.40.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.30.20.png" src="images/sharepics/Screenshot-2009.11.22-13.30.20.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.30.20.png" src="images/sharepics/Screenshot-2009.11.22-13.30.20.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.31.01.png" src="images/sharepics/Screenshot-2009.11.22-13.31.01.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.31.34.png" src="images/sharepics/Screenshot-2009.11.22-13.31.34.png" /&gt;
&lt;p&gt;&lt;strong&gt;Support&lt;/strong&gt; If you have comments, suggestions or need help with the application
please send an email to bcl at this domain.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;iPhone or iPod Touch&lt;/li&gt;
&lt;li&gt;Bluetooth&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;a class="reference external image-reference" href="http://itunes.apple.com/us/app/sharepics/id342123800?mt=8"&gt;&lt;img alt="images/misc/appstore.png" src="images/misc/appstore.png" /&gt;&lt;/a&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;em&gt;v1.0&lt;/em&gt; Initial release&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 05 Dec 2009 00:00:00 -0000</pubDate><category>iPhone</category></item><item><title>SharePics Rejected by Apple!</title><link>http://brianlane.com/sharepics-rejected-by-apple.html</link><description>&lt;p&gt;So I got my first rejection from the App Store today. According to their email
it was rejected because - we cannot post your application because it appears to
include features that resemble Polariod photographs. Polaroid has previously
objected to other applications that include features that resemble Polaroid
photographs, and believes that such features infringe its rights.&lt;/p&gt;
&lt;p&gt;Say what? Now, I'm the first to admit that my icon is a bit simple. But it
seems like a reach for Polaroid to be able to claim that all black squares on
white rectangles are infringing on their rights. And Apple did suggest that you
use distinctive colors and a strong outline to promote user recognition. Here
are some other screenshots from the app:&lt;/p&gt;
&lt;img alt="images/sharepics/old-icon.png" src="images/sharepics/old-icon.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.12.05-14.31.03.png" src="images/sharepics/Screenshot-2009.12.05-14.31.03.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.29.40.png" src="images/sharepics/Screenshot-2009.11.22-13.29.40.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.30.20.png" src="images/sharepics/Screenshot-2009.11.22-13.30.20.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.30.20.png" src="images/sharepics/Screenshot-2009.11.22-13.30.20.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.31.01.png" src="images/sharepics/Screenshot-2009.11.22-13.31.01.png" /&gt;
&lt;img alt="images/sharepics/Screenshot-2009.11.22-13.31.34.png" src="images/sharepics/Screenshot-2009.11.22-13.31.34.png" /&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 03 Dec 2009 10:44:00 -0000</pubDate><category>iPhone</category><category>Pictures</category></item><item><title>Backups, Archives and Overheating Processors</title><link>http://brianlane.com/backups-archives-and-overheating-processors.html</link><description>&lt;p&gt;A few (ahum) years ago I &lt;a class="reference external" href="http://www.linuxjournal.com/article/6558"&gt;wrote an article&lt;/a&gt; for Linux Journal on building a
RAID system. While that exact system no longer exists, I do still have a RAID5
setup that I use with &lt;a class="reference external" href="http://backuppc.sourceforge.net/"&gt;BackupPC&lt;/a&gt; to backup
all the systems on my LAN. As I wrote about in my &lt;a class="reference external" href="http://brianlane.wordpress.com/2009/11/07/kvm-on-fedora11/"&gt;KVM article&lt;/a&gt;, I have updated
my main Linux box to Fedora11. It had been out of backup rotation for about a
year, since I have mostly been using my Mac Mini and everything on the Linux
box was checked out of a remote &lt;a class="reference external" href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt;
repository. I wanted to archive the old system's backup and add it to the
backup rotation again.&lt;/p&gt;
&lt;p&gt;In all my years of using BackupPC I had somehow
missed the archive feature. I've used it to recover files by
writing them to a /tmp/ directory on a remote system or download a
tar of selected files but hadn't realized that you could also
create a gigantic tar of all the files in the current backup. To
get this setup I had to do several things:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Add a new dns alias for the system to write the archive to. I
use the same system that BackupPC runs on for this.&lt;/li&gt;
&lt;li&gt;Add a new host in the 'Edit Hosts' page, I named it the same
thing as the new DNS alias&lt;/li&gt;
&lt;li&gt;Edit the new host's config and in the 'Xfer' page set
'XferMethod' to Archive instead of rsync&lt;/li&gt;
&lt;li&gt;Change the 'ArchiveSplit' option to 1000 to split the tar into
1G files to make it easy to handle&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And presto! I could now dump archives of the backups to the local system and
then burn them to DVD. I also wanted to include a directory of all the files
along size the archive. Since the tar is actually split up into pieces you need
to join them together in order to get a full listing out of them. Since tar was
written to be used with streaming tapes this means all you need to do is cat
them to a tar process reading from standard input and write the output into a
file. Like this:&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;cat host.tar.bz2.a? | tar tvjf - &amp;gt; ./directory.txt&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;This streams all the archive files to tar which is reading from standard input
and writes the output to the directory.txt file. This can take quite a while.&lt;/p&gt;
&lt;p&gt;So at this point in the day I finally had the old system image written to a
couple of DVD's. Now it was time to switch the backup back on and catch up with
the current system image. I added a few new directories to the list to backup
(I usually only backup /etc, /root and /home). This included my new libvirt
virtual images. In all it amount to about 96G worth of files. The LAN
bottleneck is the 100Mb NIC in the backup system. It was pushing around 45Mb
for several hours, chugging its way through the backup. Then something strange
happened.&lt;/p&gt;
&lt;p&gt;The backup server turned off. No warning, just click. nothing. I rebooted it,
it ran its filesystem checks with no problems. I dug through the logfiles and
there was nothing in them to indicate a problem of any kind. So I restarted the
backup and it ran for about another 30 minutes before doing the same thing.
This system &lt;strong&gt;never&lt;/strong&gt; dies on me, or at least ever since I put in an Antec 500W
power supply it doesn't just die.&lt;/p&gt;
&lt;p&gt;I started with the obvious, checking for bus errors in the logs. I ran
memtest86 on it for a bit. Then I took a look at the BIOS health readings. Even
after being relativly idle for 15 minutes the CPU temp was at 63C. Now, this
system is a 2.9GHz Celeron D. The max temp is somewhere around 67C. So I was
probably baking the heck out of the CPU and it was doing a thermal shutdown.
Consumer CPUs like the Celeron just aren't designed for this kind of abuse. But
that never stops me from trying to squeeze every last cent out of a system.&lt;/p&gt;
&lt;p&gt;The heatsink had what I'd call a moderate amount of dust on it, but it was
mostly on the top not crammed down in the fins like I have sometimes seen. I
pulled it odd and the CPU was glued to it with heatsink grease. I blew out the
dust (canned air is so much fun!), cleaned things off, gave it some new grease
and re-installed.&lt;/p&gt;
&lt;p&gt;I fired up the backup and again after a short period of time it died. I finally
setup the sensors package on the system and it told the story -- it was still
overheating. The fan was only running at about 2.7k rpms so I swapped in a
spare Tornado fan, cranked it up to its maximum of&amp;nbsp; 5300 rpm and restarted the
backup. The CPU now maxes out around 57C and the backups all run to completion
so things seem to be happy.&lt;/p&gt;
&lt;p&gt;This also reminds me that I really need to blow the dust out of the heatsinks
in the other systems around here -- I don't think I've done that in over a
year. I really should have a regular maintenance schedule instead of waiting
for failures to happen. I guess I need the extra excitement or something.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Tue, 10 Nov 2009 23:32:00 -0000</pubDate><category>Linux</category><category>OS</category><category>Backup</category></item><item><title>KVM on Fedora11</title><link>http://brianlane.com/kvm-on-fedora11.html</link><description>&lt;p&gt;I've been a &lt;a class="reference external" href="http://www.vmware.com"&gt;VMWare Workstation&lt;/a&gt; user for years and
have generally been pretty happy with it; but it is significantly slower than
bare metal, especially when it comes to disk i/o. One of my responsibilities
for work is creating and maintaining a custom &lt;a class="reference external" href="http://www.fedoraproject.org"&gt;Fedora&lt;/a&gt; distribution. This requires building new rpm
packages and then creating a livecd iso for the install of the system. Lots of
disk i/o involved in reading and creating the disk image meant that I was
running Fedora9 as my native desktop.&lt;/p&gt;
&lt;p&gt;Last year I upgraded to a Core2 Duo system. Not realizing that some of them
&lt;strong&gt;don't&lt;/strong&gt; have virtualization support I bought the cheapest one that &lt;a class="reference external" href="http://www.newegg.com"&gt;NewEgg&lt;/a&gt; had available at the time. After a bit of thrashing
about I realized that the E2200 I had wouldn't support Xen, qemu or virtualbox.
So I continued to use VMWare Workstation and a bare-metal Fedora9 installation
for my build environment.&lt;/p&gt;
&lt;p&gt;This wasn't too bad a first. That is until I added a second ACER 22&amp;quot; widescreen
to my desktop and discovered that Fedora9 has trouble with the nVidia graphics
chipset (GeForce 7050/nForce 610i) on this motherboard. The display resolution
is squareish. On a widescreen monitor this results in everything looking short
and fat. It isn't terribly noticeable, but does become annoying after using it
all day.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Moore's_law"&gt;Moore's Law&lt;/a&gt; the prices
on the low end Core2 Duo's (E3300) with virtualization support have dropped to
the same level as the processor I bought last year. Last week I swapped in the
new CPU (&amp;lt;10 minute job), and moved my development environment over to Fedora11
and it's excellent virtualization support using libvirt. I've mostly been using
the GUI tools for setup and management and have been &lt;em&gt;very&lt;/em&gt; happy with things
so far.&lt;/p&gt;
&lt;p&gt;One of the first things I needed to do was move the default storage pool onto
my large drive (ok, 500G isn't really large by today's standards but it is the
biggest one I have). I didn't quite get the concept of storage pools at first
and was trying to specify a new path when I setup the new virt. Instead what
you need to do is edit the storage of the host system, add a new pool using a
directory of files on the larger drive, and then create a new image file in the
pool for use with the virt you are going to setup.&lt;/p&gt;
&lt;p&gt;The next hurdle was getting bridged networking
setup. Some of the virts that I use are test images for production
web servers (I like to virtualize and test as much of the
production environment as possible). To do this I followed the
directions over on the
&lt;a class="reference external" href="http://wiki.libvirt.org/page/Networking#Bridged_networking_.28aka_.22shared_physical_device.22.29"&gt;libvirt webpage&lt;/a&gt;,
basically editing a couple of files in
/etc/sysconfig/network-scripts.&lt;/p&gt;
&lt;p&gt;ifcfg-eth0 now looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;DEVICE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;eth0
&lt;span class="nv"&gt;HWADDR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;00:21:97:9e:e1:15
NM&lt;span class="se"&gt;\_&lt;/span&gt;CONTROLLED&lt;span class="o"&gt;=&lt;/span&gt;no
&lt;span class="nv"&gt;ONBOOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes
&lt;span class="nv"&gt;BRIDGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;br0
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And a new file, ifcfg-br0 looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Bridge device&lt;/span&gt;
&lt;span class="nv"&gt;DEVICE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;br0
&lt;span class="nv"&gt;TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Bridge
&lt;span class="nv"&gt;BOOTPROTO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dhcp
&lt;span class="nv"&gt;ONBOOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes
&lt;span class="nv"&gt;DELAY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
NM&lt;span class="se"&gt;\_&lt;/span&gt;CONTROLLED&lt;span class="o"&gt;=&lt;/span&gt;no
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After doing this I restarted networking and now br0 shows up as the default
interface when setting up new virtuals with the GUI tools. One snag I ran into
is that BOOTPROTO=dhcp is case sensitive -- DHCP will not work and will cause
some amount of frustration until you realize this.&lt;/p&gt;
&lt;p&gt;Within a couple of hours I was able to move my Fedora9 build and test
environments over to virtuals, including the i/o intensive iso building
process. I haven't made any objective measurements, but it runs almost as
quickly as it did on the bare metal install and significantly faster than when
I tried running it under VMWare. Now my screen runs properly, thanks to the
nouveau driver used in Fedora11, and I can fire up more virtuals without
bogging down the system like it would with VMWare. I may miss the snapshot
option of VMware eventually, but for now the virt-clone utility works just fine
for my needs.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 07 Nov 2009 10:04:00 -0000</pubDate><category>Linux</category><category>Fedora</category><category>KVM</category><category>Virtualization</category></item><item><title>iPhone Tech Talk Seattle</title><link>http://brianlane.com/iphone-tech-talk-seattle.html</link><description>&lt;p&gt;Today is the Seattle iPhone developer talk event. I'm headed for the ferry in a
few minutes and figured I would give the Wordpress iPhone app a try. I'll
update this post as I have time today.&lt;/p&gt;
&lt;p&gt;Well, it was a long day! I used twitter a bit, but didn't have a chance for any
longer updates here. Here are my impressions and short notes from the sessions&lt;/p&gt;
&lt;p&gt;I attended. I attended 4 presentations: UI Design Essentials, Adding In App
Purchase, Core Data, Testing and debugging and Networking.&lt;/p&gt;
&lt;p&gt;All the talks were packed with good information. The speakers were of varying
levels of energy. This means that it was sometimes hard to concentrate on the
material because the speaker was a bit boring.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UI Design Essentials&lt;/strong&gt; - Your icon is your business card and it will make or
break the success of your app. Most users buy with their phones (this surprised
me, I buy with iTunes) so all they see is your icon and the name of your app in
their search results. The brain processes shapes and colors first, then
textureand smaller details. This means your icon should have distinctive colors
and a clear outline, not a complicated and cluttered design. You should be
using sound in your app. People respond instinctually to sounds, they make your
app more polished. You should support landscape mode. Studies show that those
under 35 prefer two thumb landscape and those over prefer single finger typing.
Read the Human Interface Guideline doc. It will tell you how to design an
excellent User Interface. Too many people haven't read it, or have only skimmed
it. (This could be said for most of Apple's documents, they have a huge amount
of useful information available if people would only take advantage of it).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In App Purchase&lt;/strong&gt; - This talk mostly covered the steps needed to enable and
test purchases in your app. You can setup test itunes accounts to use to test
the buying process. There are 3 types of purchases: Consumables,
non-Consumables and subscriptions. It is up to you to track subscription
information and expiration. You should give uses the option of restoring
everything they have bought, for cases where they are setting up a new (ie.
replacement) phone. Consumables are not restored. In App Purchase is a game
changer. No more need for supporting 2 versions of an app.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Working With Core Data&lt;/strong&gt; - This is the one where I almost fell asleep. Being
right after lunch (Ham sandwich, potato salad, chips and an Apple) probably
didn't help. Core Data is backed by SQLite. Don't put blobs in the db, the file
system is much better at handling that. Normalized vs. denormalized. If you
aren't careful you can end up with some messy tables. Table schema is private,
no direct access, unless you want to break it. Core Data can batch results to
save memory. Returns a NSArray looking object that will return more objects as
you iterate through it but really only holds X in memory at one time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Testing and Debugging&lt;/strong&gt; - Covered how to add Logical and App Unit Testing
with Xcode. Support is built in, but setup of the in-app one was a bit
convoluted so I'll have to look it up. Static analysis using clang is awesome.
Built into Xcode, uses the UI to show you how it came to its conclusions.
Suggested that a new build target be created with it turned on since it does
take longer than a normal build (and doesn't really need to be run every time).
I was surprised it didn't cover Instruments. Covered ad-hoc distribution for
beta testers, building and distributing the executable and provisioning
profile. Also stressed the importance of saving the executable and dsym
someplace safe -- when you get a crash report you must have the exact binary
and debug symbols the user is running. It isn't enough to just rebuild them, so
zip them up and stuff them into source control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Networking&lt;/strong&gt; - Covered 'normal' networking first. Use the highest level
classes unless absolutely necessary -- you will end up writing unneeded code
otherwise. Don't use threaded synchronous functions, use delegates instead.
Covered Bonjour, registering a bonjour name, browsing for services on the LAN.
Don't setup the discovered services when you find them, it is a waste of time
and can slow things down dramatically. Wait until the user picks the
device+service they want to connect to. Covered GameKit. Works with WiFi and
BT, unless you are using PeerPicker, which only works with BT right now.
Supports peer to peer voice chat, example source is still in the works. Lots of
new and updated networking example code is available.&lt;/p&gt;
&lt;p&gt;Overall I found the conference to be useful and informative. I would have liked
them to have Q&amp;amp;A but the speakers always ran out of time. The environment was
different than the open source conferences I have attended (LFNW, OSCON). There
was no interaction with the audience, and very little interaction within the
audience. At LFNW especially you have alot of feedback in the audience, both
with questions asked and questions answered by other attendees.&lt;/p&gt;
&lt;p&gt;I was actually expecting the content to be a bit more over my head (I do not
consider myself an ObjC expert), but I found it all to be understandable and
accessible, but not too simplistic. I think Apple has done a good job of
targeting the middle road of iPhone developers. There were a few times when I
felt like the speaker was talking down a bit, but it likely was only because of
the potential mixture of experience present.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Mon, 02 Nov 2009 08:10:00 -0000</pubDate><category>iPhone</category><category>Objective C</category></item><item><title>LinuxFest Northwest 2008 Presentation</title><link>http://brianlane.com/linuxfest-northwest-2008-presentation.html</link><description>&lt;div class="section" id="replace-yourself-with-python"&gt;
&lt;h2&gt;Replace Yourself With Python&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/lfnw2008/ais_download.py"&gt;ais_download.py&lt;/a&gt; - setup passwords for product download website&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/lfnw2008/mail-grep.py"&gt;mail-grep.py&lt;/a&gt; - Use IMAP and python to grep mail for specific strings&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/lfnw2008/mail_customers.py"&gt;mail_customers.py&lt;/a&gt; - Use smtplib and python to announce new releases to customers&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/lfnw2008/release.txt"&gt;release.txt&lt;/a&gt; - Template file used by mail_customers.py&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/lfnw2008/ssh_thread.py"&gt;ssh_thread.py&lt;/a&gt; - Threaded skeleton to run a ssh command on multiple servers in parallel with randomized start time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 01 May 2008 00:00:00 -0000</pubDate><category>Linux</category><category>Bellingham</category><category>Linuxfest</category><category>KPLUG</category><category>TACLUG</category><category>BLUG</category></item><item><title>System Health Monitoring Software</title><link>http://brianlane.com/systemhealth.html</link><description>&lt;!-- image: http://neil.brianlane.com/~monitor/eth0-32hours.png
:target: http://neil.brianlane.com/~monitor/ --&gt;
&lt;p&gt;System Health Monitor for Linux is a handy &lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt; program that will setup
your system to generate &lt;a class="reference external" href="http://oss.oetiker.ch/rrdtool/"&gt;RRD Graphs&lt;/a&gt; of network interface traffic, system
load, memory usage, disk space and inode usage and graphs of the number of
running processes. It features a user-friendly interactive configuration mode
and auto-generated html pages. Just point your web server to the health_html
directory to get an overview of the status of your machine. You can see
examples of it in operation &lt;a class="reference external" href="http://neil.brianlane.com/~monitor/"&gt;here on my machine&lt;/a&gt;&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Current Version&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/systemhealth/systemhealth-1.0.tar.bz2"&gt;Download v1.0 here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/systemhealth/"&gt;Browse previous releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Current systems can update their html, as long as it has not been hand-edited,
by running &lt;tt class="docutils literal"&gt;systemhealth.py &lt;span class="pre"&gt;--html&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;em&gt;v0.5.1&lt;/em&gt; Initial release&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v0.6&lt;/em&gt; Changes the license to GPL v2.0 and fixes a problem with newer
kernels (v2.6.10) that include a new entry in /proc/meminfo
also fixed command line processing so that --log and --graph can be used
at the same time.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v0.7&lt;/em&gt; Added support for creating graphs from the output of external
programs using the --add command. See the README for instructions. This
allows adding things like temperature monitoring to the health graphs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v0.8&lt;/em&gt; Added escaping of ':' character in rrd COMMENT sections for
compatibility with newer releases of &lt;cite&gt;RRD Graphs&lt;/cite&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v0.9&lt;/em&gt; Changed spacing in COMMENT sections so that they look better
with newer releases of rrdtool. Left justified the status info so that it
won't be cut off by the right side of the graph. Added a check for the
'external' section, older versions won't have it in their config files.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;v1.0&lt;/em&gt; Added --new switch which will prompt for processes that aren't
in the config file, allowing easy addition of new services.&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 20 Jan 2008 00:00:00 -0000</pubDate><category>Python</category></item><item><title>Safari Books Online Review</title><link>http://brianlane.com/safari-books-online-review.html</link><description>&lt;p&gt;&lt;a class="reference external" href="http://www.safaribooksonline.com/"&gt;http://www.safaribooksonline.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Full disclosure:&lt;/em&gt; I was give a 60 day 10 slot bookshelf account on Safari
Books for the purposes of reviewing it, with the understanding that I would
receive a full year free when I posted a review to the &lt;a class="reference external" href="http://www.kplug.org"&gt;KPLUG&lt;/a&gt; webpage. No
other strings were attached.&lt;/p&gt;
&lt;p&gt;The Safari Tech Books project is an amazing undertaking. The online catalog
includes 2013 (at the time of this writing) books from O'Reilly, SAMS, QUE,
Cisco Press, and several other publishers. The full text and diagrams of all of
these books are online and fully searchable.&lt;/p&gt;
&lt;p&gt;There are two subscription types, the whole library and a bookshelf
subscription. The sample account I used was a bookshelf subscription with 10
slots. You can search all of the books in the library, but you can only see a
few paragraphs surrounding your search results. You have to place the book into
your bookshelf to be able to see the whole text of the book. The book has to
remain in your bookshelf for at least 30 days. Some books take up less than a
slot and some can take up more, the system will warn you before the book is
added.&lt;/p&gt;
&lt;p&gt;You have to be careful not to fill up your bookshelf right away. With over 2000
books available it is easy to find interesting and relevant books! I managed to
keep 2 slots open just in case I found something I really needed before my
previous slots expired.&lt;/p&gt;
&lt;p&gt;The books can be searched using a full text search engine (with the option to
limit searches to just code snippets), or there is a large category tree on the
left, with the books categorized every way imaginable. Top level categories
include subjects like Applied Sciences, Business, Certification, Hardware,
Multimedia, etc. I found the tree view a bit hard to navigate, with so many
books and so many subjects it was difficult to categorize what I was looking
for.  Text searches were much easier to use, and they support author, ISBN and
title searches as well.&lt;/p&gt;
&lt;p&gt;Once you have a book in your bookshelf you can read the whole book, cover to
cover, page by page. I found the default text to be a bit small, but that is
easily corrected with a CTRL-+ in Mozilla. On the left the table of contents is
displayed that makes it easy to skip around inside the book. This bar can be
hidden to make the text more readable on smaller screens. Your searches can
also be limited to the current book you are viewing.&lt;/p&gt;
&lt;p&gt;You can add bookmarks to book sections as you are viewing them but you can't
name the bookmarks though. You can also add public notes that others can read
or private notes for your own use (the electronic equivalent of writing in the
margins). The notes are only shown in the 'view notes' page though. It would
make more sense to me if the notes were appended to the bottom of the page
where they have been attached, that way they can easily be viewed in context.
The documentation for MySQL is done this way and is very effective, with users
able to add or correct content.&lt;/p&gt;
&lt;p&gt;The system also keeps track of your recent searches, that way you can easily
view the results of a search without remembering exactly what it was you
entered for the search. It also keeps a list of the recent pages that you have
viewed. This list can be a bit monotonous if you are reading a book
page-by-page.&lt;/p&gt;
&lt;p&gt;When searching the text is highlighted, making it easily visible as you scan
the page. In some instances it can be distracting (eg. searching for 'video' in
the video section of PC Hardware in a Nutshell), so there is an option that
will redisplay the page with the search term highlights turned off.&lt;/p&gt;
&lt;p&gt;I wish I could tell you how much this service costs. But I could not find any
pricing structure on the website. They do allow you to sign up for a free 30
day trial account. The system is oriented towards the 'enterprise', not
individual users. I think the service as it currently exists is an excellent
service for large companies. It makes it easier to find the information that
you know is buried in your stack of O'Reilly books, as well as allows you to
make your own electronics notes.&lt;/p&gt;
&lt;p&gt;But I wonder if we will see a 'personal' version of this? Something with a
limited number of slots and a slot lifetime of a week would be more useful to
someone like me who always seems to be moving from project to project (or
interest - I call it chasing butterflies).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; There is a personal version available starting at $9.95 a month.
See &lt;a class="reference external" href="http://my.safaribooksonline.com/subscribe"&gt;Safari Books Online&lt;/a&gt; for
more information.&lt;/p&gt;
&lt;p&gt;The service is easy to use, and was always available when I needed it. But if
you are depending on it as your primary information source for your business I
wonder if there is a on-site version available? Something that doesn't depend
on the Internet for delivery (doubtful, it would be too easy to pirate and
distribute to the rest of the organization).&lt;/p&gt;
&lt;p&gt;I would like to thank O'Reilly for giving me the opportunity to examine this
new service. Their books have always been excellent and this takes publishing
in a new direction.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 01 Jan 2006 00:00:00 -0000</pubDate><category>Safari Books</category><category>Review</category></item><item><title>LinuxFest Northwest 2005 Presentation</title><link>http://brianlane.com/linuxfest-northwest-2005-presentation.html</link><description>&lt;div class="section" id="msp430-programming-with-linux"&gt;
&lt;h2&gt;MSP430 Programming with Linux&lt;/h2&gt;
&lt;p&gt;This is a presentation that I gave at &lt;a class="reference external" href="http://linuxfestnorthwest.org"&gt;Linux Fest Northwest&lt;/a&gt; 2005. It covers
PC Board layout in Linux and programming the TI MSP430 microprocessor.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="static/msp430_linux/index.html"&gt;Slide images are here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="static/msp430_linux/msp430.mgp"&gt;Magic Point source is here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;This presentation was also the basis for an article published in
&lt;a class="reference external" href="http://www.linuxjournal.com/article/8682"&gt;Linux Journal Issue #142&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 01 May 2005 00:00:00 -0000</pubDate><category>Linux</category><category>Linuxfest</category><category>Bellingham</category><category>KPLUG</category><category>TACLUG</category><category>BLUG</category></item><item><title>PICprg</title><link>http://brianlane.com/picprg.html</link><description>&lt;p&gt;PICprg is programmer software for &lt;a class="reference external" href="http://www.microchip.com"&gt;Microchip&lt;/a&gt; PIC
programmers. It is designed to work with any of the PC parallel port types of
programers for the PIC16C84 processors. It features a very flexible
configuration menu where you can set the parallel port pin for each function,
and test them. Setup is easy and only requires a voltmeter. It includes a user
friendly setup menu, memory dump screen with hex display.&lt;/p&gt;
&lt;p&gt;You should also read my &lt;a class="reference external" href="http://www.linuxjournal.com/article.php?sid=3045"&gt;Linux Journal article&lt;/a&gt; article describing how
picprg works.&lt;/p&gt;
&lt;p&gt;For more information on PIC programming hardware see my &lt;a class="reference external" href="ftp://ftp.brianlane.com/pub/picarchive/"&gt;mirror&lt;/a&gt; of &lt;a class="reference external" href="http://people.man.ac.uk/~mbhstdj/files/"&gt;David Tait's&lt;/a&gt; excellent piclinks page from 1999.&lt;/p&gt;
&lt;img alt="images/picprg/picprg.main.gif" src="images/picprg/picprg.main.gif" /&gt;
&lt;img alt="images/picprg/picprg.config.gif" src="images/picprg/picprg.config.gif" /&gt;
&lt;img alt="images/picprg/picprg.display.gif" src="images/picprg/picprg.display.gif" /&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;li&gt;ncurses&lt;/li&gt;
&lt;li&gt;Parallel port PIC programmer hardware&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Current Release&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/picprg/picprg-2.3.0.tar.bz2"&gt;Download PICprg v2.3.0 here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/picprg/"&gt;Browse previous PICprg releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last"&gt;
&lt;li&gt;&lt;dl class="first docutils"&gt;
&lt;dt&gt;&lt;em&gt;2.1&lt;/em&gt; fixes a couple of things:&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;Error setting the config register (non-RC osc. wouldn't work)&lt;/li&gt;
&lt;li&gt;Error and Confusion with Intel 16 file format cleared up. It now will
read Intel 16 and 8m files automatically.&lt;/li&gt;
&lt;li&gt;Added display of addresses as they are being read, written, and verified&lt;/li&gt;
&lt;li&gt;Added support for no-color mode (-m switch or automatic detection)&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;v2.2&lt;/em&gt; fixes problems with programmers that use open collector outputs,
like the PIC-1 from ITUtech.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;v2.3&lt;/em&gt; Yes, after years of waiting the new release of PICprg is
here. There really isn't anything special, except that it now works
with Linux kernel versions 2.2.x and 2.4.x -- Thanks go to Lee Olsen for
providing the direction for these improvements.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sun, 13 Feb 2005 00:00:00 -0000</pubDate><category>Linux</category><category>PIC</category></item><item><title>PhotoAlbum</title><link>http://brianlane.com/photoalbum.html</link><description>&lt;p&gt;PhotoAlbum is a &lt;a class="reference external" href="http://www.perl.org"&gt;Perl&lt;/a&gt; program that creates a nice web friendly photo album of
your pictures. It creates top level index files and individual image pages with
optional captions, image statistics and file names using plain html for easy
uploading to any web host. Navigation buttons make moving between pictures
easy.&lt;/p&gt;
&lt;p&gt;The Album generated it suitable for posting to a webpage, or burning to cdrom.
One of the things I like to do is to take tons of pictures at family events and
then burn cds for everyone. Having a nice HTML based photo album cdrom of an
event is a big plus!&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;Perl&lt;/li&gt;
&lt;li&gt;Image Magick&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="File::copy"&gt;File::copy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="File::Basename"&gt;File::Basename&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;POSIX&lt;/li&gt;
&lt;li&gt;Getopt::Std&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Current Release&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/photoalbum/photoalbum-1.0.0.tar.bz2"&gt;Download photoalbum v1.1.0 here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/photoalbum/"&gt;Browse previous releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;em&gt;1.0.0&lt;/em&gt; initial release&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 12 Feb 2005 00:00:00 -0000</pubDate><category>Perl</category><category>Photos</category></item><item><title>SN-15 PalmOS AR-15 Serial Number List</title><link>http://brianlane.com/sn15.html</link><description>&lt;p&gt;This is a simple PalmOS application that contains all of the information that I
could find on the serial number ranges for various AR-15 manufacturers
indicating whether or not the rifle is a 'pre-ban' rifle or not.&lt;/p&gt;
&lt;p&gt;Select the manufacturer from the popup menu and all of the information that I
have found for that manufacturer will be displayed in the main screen, if it is
too large to fit on one screen the scroll bar will be enabled, use it or the
up/down buttons to scroll the information.&lt;/p&gt;
&lt;img alt="images/sn15/SN15-main.gif" src="images/sn15/SN15-main.gif" /&gt;
&lt;img alt="images/sn15/SN15-list.gif" src="images/sn15/SN15-list.gif" /&gt;
&lt;img alt="images/sn15/SN15-olyinfo.gif" src="images/sn15/SN15-olyinfo.gif" /&gt;
&lt;p&gt;Most of this info was taken from the &lt;a class="reference external" href="http://www.ar15.com"&gt;AR15.com&lt;/a&gt;
serial number FAQ in 1999. I have added recent data from Olympic Arms on their
serial number ranges which they released after their June 7, 2000 fire.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a class="reference external" href="http://www.kplug.org/~mhjack"&gt;Mike Jackson&lt;/a&gt; for the inspiration
for this program.&lt;/p&gt;
&lt;p&gt;This program should work on all PalmOS devices, if you have problems with it
please email me the details fo the device you are using and the problem(s)
encountered.&lt;/p&gt;
&lt;p&gt;The information contained in this program is for educational purposes only. It
should not be considered the final word on anything and you should contact the
rifle's manufacturer for a definitive answer. This information is meant only as
a guide and has not been authorized or certified by any manufacturer.&lt;/p&gt;
&lt;p&gt;Included is the GNU 'C' source code used to write this program. My
development enviornment is a Debian 2.2 Linux system using the GNU compiler
with cross-compiling for PalmOS. It is released under the GNU Public License
v2.0 and is free to use and modify and learn from.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; In September 2004 the 'assault' weapon ban expired. It looks, at
least for now, like it is not going to be renewed. Tragically the inspiration
for this program, &lt;a class="reference external" href="http://www.kplug.org/~mhjack"&gt;Mike Jackson&lt;/a&gt; died of a
heart attack on March 28, 2003. He is greatly missed.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;PalmOS device&lt;/li&gt;
&lt;li&gt;GNU gcc PalmOS cross compiler (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Current Release&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/sn15/sn15-2.0.0.tar.bz2"&gt;Download SN-15 v2.0.0 here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/sn15/"&gt;Browser previous releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;em&gt;2.0.0&lt;/em&gt; final release&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.ar15.com/content/legal/"&gt;AR15.com serial # FAQ and Legal FAQs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.olyarms.com"&gt;Olympic Arms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.mp5.net/info/preban.htm"&gt;Pre/Post Ban Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.biggerhammer.net/ar15/ar15serial.html"&gt;BiggerHammer Colt Serial # List&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 12 Feb 2005 00:00:00 -0000</pubDate><category>PalmOS</category><category>AR-15</category><category>Guns</category></item><item><title>TrollBridge Network Authentication</title><link>http://brianlane.com/trollbridge.html</link><description>&lt;p&gt;TrollBridge is a set of &lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt; scripts and iptable configuration that allows
you to capture unknown network clients and authenticate them before allowing
them to access the network (local, internet, 802.11 WiFi, etc.). It is based on
the firewall script from &lt;a class="reference external" href="http://nocat.net/moin/NoCatSplash"&gt;NoCatSplash&lt;/a&gt;,
but is written in &lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt; instead of 'c'.&lt;/p&gt;
&lt;p&gt;It can be used to to setup a network hot-spot for your business, school or
home. The only authorization methods currently available are a skeleton
username/password example, and an example using &lt;a class="reference external" href="http://www.ibutton.com"&gt;iButton devices&lt;/a&gt;. When a unknown MAC addresses tries to make a
connection to the protected network the iptables rules redirect any access (web
or otherwise) to port 5280 where the Apache server then displays the
authentication page. Yes, MAC addresses are used to keep track of authorized
users, so this system is susceptible to MAC spoofing.&lt;/p&gt;
&lt;p&gt;The scripts are not 'plug and play', you will need to customize them for your
unique situation, as well as modify your iptables settings and add a virtual
host to the Apache web server.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;iptables&lt;/li&gt;
&lt;li&gt;Apache Web Server&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Some experience with networking and writing scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Current Release&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/trollbridge/trollbridge-0.6.0.tar.bz2"&gt;Download TrollBridge v0.6.0 here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/trollbridge"&gt;Browse previous releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 12 Feb 2005 00:00:00 -0000</pubDate><category>Network</category><category>Captive Portal</category></item><item><title>up2dateiso</title><link>http://brianlane.com/up2dateiso.html</link><description>&lt;p&gt;up2dateiso is a &lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt; script that will create current CD .iso images for
&lt;a class="reference external" href="http://www.redhat.com"&gt;RedHat 9&lt;/a&gt;, &lt;a class="reference external" href="http://fedora.redhat.com"&gt;Fedora Core 1&lt;/a&gt; and &lt;a class="reference external" href="http://www.centos.org"&gt;CentOS 3.1&lt;/a&gt; with the
latest rpm updates available. It also includes a custom &lt;a class="reference external" href="http://www.kplug.org"&gt;KPLUG&lt;/a&gt; splash screen identifying when it was last updated.&lt;/p&gt;
&lt;img alt="images/up2dateiso/fc1_splash.png" src="images/up2dateiso/fc1_splash.png" /&gt;
&lt;p&gt;This project attemps to update downloaded iso images with the latest security
releases from the distributions. It support RedHat 9, Fedora Core 1 and 2, and
CentOS 3.1 to one degree or another.&lt;/p&gt;
&lt;p&gt;There is an &lt;a class="reference external" href="https://lists.brianlane.com/mailman/listinfo/up2dateiso/"&gt;up2dateiso mailing list&lt;/a&gt; that can help
provide support.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; This script currently doesn't work well with anything other than FC1
and RH9 (and even those are not 100% right), the problem is that in the
truncated iso rebuild that I use something gets mixed up in the package list
and the installer asks for the CDs out of sequence and you end up swapping them
many times instead of only once.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Current Release&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/up2dateiso/up2dateiso-1.3.0.tar.bz2"&gt;Download up2dateiso v1.3.0 here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/up2dateiso/"&gt;Browse previous Releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;em&gt;1.0.0&lt;/em&gt; initial release with RedHat 9 and Fedora Core 1 support&lt;/li&gt;
&lt;li&gt;&lt;em&gt;1.1.0&lt;/em&gt; attempted to add support for Fedora Core 2. It doesn't work right.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;1.2.0&lt;/em&gt; Added support for RHEL 3 clone &lt;a class="reference external" href="http://www.centos.org"&gt;CentOS 3.1&lt;/a&gt;
which can be updated from a Fedora Core 1 install or from a CentOS install.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;1.3.0&lt;/em&gt; implements using local copies of genhdlist and implantisomd5 if
the library checks on the ones from the iso fail. I still cannot get FC2 to
work correctly (asks for 2nd CD way too many times during install). But this
may be closer to a solution, and may work for others. This version also adds
a timestamp to the bottom of the splash image, that way you can always tell
when the iso was created.&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 12 Feb 2005 00:00:00 -0000</pubDate><category>Fedora</category><category>ISO</category><category>Updates</category></item><item><title>Snapple Real Facts</title><link>http://brianlane.com/snapple-real-facts.html</link><description>&lt;p&gt;&lt;strong&gt;UPDATE 07/15/2003:&lt;/strong&gt; I've put the Snapple Real Fact Page back up, even
though I am no longer running a wiki. I'll start adding to my drinking
list as well.&lt;/p&gt;
&lt;p&gt;Where did the list of Snapple Real Facts go, you are asking? Well
here's the answer:&lt;/p&gt;
&lt;p&gt;On the previous Wiki I had a list of the caps from the Snapple bottles that I
had been drinking, in the order I saw them. Some people added a full list of
the caps, which was nice of them. But then some other morons came along and
erased my list. For some reason the WikkiTikiTavi that I was running didn't
save backups of my original pages, only the altered ones. So my list is lost
(unless archived deep inside Google somewhere).&lt;/p&gt;
&lt;p&gt;I've now switch Wiki software to one that saves all the changes, so if things
get trashed I can get back to a previously good page.&lt;/p&gt;
&lt;p&gt;And thanks to the wonders of Google's Cache I now have my old list back!
Another interesting fact is that this website appears above Snapple's own
website. (07/15/2003, it hasn't been reindexed by google yet)&lt;/p&gt;
&lt;p&gt;A collection of Snapple Real Facts, In order of when I drank them.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="7%" /&gt;
&lt;col width="93%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Number&lt;/th&gt;
&lt;th class="head"&gt;Fact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;#74&lt;/td&gt;
&lt;td&gt;You share your birthday with at least 9 million other people in the world&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#12&lt;/td&gt;
&lt;td&gt;Emus and kangaroos cannot walk backwards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#15&lt;/td&gt;
&lt;td&gt;All porcupines float in water&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#23&lt;/td&gt;
&lt;td&gt;The San Francisco cable cars are the only mobile National Monuments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#14&lt;/td&gt;
&lt;td&gt;Camel's milk does not curdle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#25&lt;/td&gt;
&lt;td&gt;The only food that doesn't spoil is honey&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#17&lt;/td&gt;
&lt;td&gt;A hummingbird weighs less than a penny&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#47&lt;/td&gt;
&lt;td&gt;Giraffes have no vocal chords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#48&lt;/td&gt;
&lt;td&gt;Cats can hear ultrasound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#66&lt;/td&gt;
&lt;td&gt;Americans eat 18 acres of pizza every day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#23&lt;/td&gt;
&lt;td&gt;The San Francisco cable cars are the only mobile National Monuments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#45&lt;/td&gt;
&lt;td&gt;Elephants are capable of swimming 20 miles a day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#54&lt;/td&gt;
&lt;td&gt;The average smell weighs 760 nanograms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#60&lt;/td&gt;
&lt;td&gt;The tongue is the fastest healing part of a human body&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#92&lt;/td&gt;
&lt;td&gt;Fish can drown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#75&lt;/td&gt;
&lt;td&gt;The average person makes about 1,140 telephone calls each year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#184&lt;/td&gt;
&lt;td&gt;The most used letters in the English language are E, T, A, O, I and N.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#164&lt;/td&gt;
&lt;td&gt;The first vacuum was so large, it was brought to a house by horses.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#165&lt;/td&gt;
&lt;td&gt;Your eye expands up to 45% when looking at something pleasing.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#122&lt;/td&gt;
&lt;td&gt;A duck can't walk without bobbing its head.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#138&lt;/td&gt;
&lt;td&gt;Hawaii is the only U.S. state that grows coffee.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#118&lt;/td&gt;
&lt;td&gt;Honeybees are the only insects that create a form of food for humans.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#127&lt;/td&gt;
&lt;td&gt;A hummingbird's heart beats 1,400 times a minute.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#158&lt;/td&gt;
&lt;td&gt;The first MTV video was &amp;quot;Video Killed the Radio Sta,&amp;quot; by the Buggles.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#186&lt;/td&gt;
&lt;td&gt;A female kangaroo is called a Flyer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#149&lt;/td&gt;
&lt;td&gt;Theodore Roosevelt was the only president who was blind in one eye.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#153&lt;/td&gt;
&lt;td&gt;The speed limit in NYC was 8 mph in 1895.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#122&lt;/td&gt;
&lt;td&gt;A duck can't walk without bobbing its head.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#181&lt;/td&gt;
&lt;td&gt;The first jukebox was located in San Francisco in 1899.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#127&lt;/td&gt;
&lt;td&gt;A hummingbird's heart beats 1,400 times a minute.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#131&lt;/td&gt;
&lt;td&gt;Penguins have an organ above their eyes that converts seawater to fresh water.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#158&lt;/td&gt;
&lt;td&gt;The first MTV video was &amp;quot;Video Killed the Radio Star,&amp;quot; by the Buggles.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#178&lt;/td&gt;
&lt;td&gt;The first ballpoint pens were sold in 1945 for $12.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#47&lt;/td&gt;
&lt;td&gt;Giraffes have no vocal chords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#28&lt;/td&gt;
&lt;td&gt;Chewing gum while peeling onions will keep you from crying&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#119&lt;/td&gt;
&lt;td&gt;The hummingbird is the only bird that can fly backwards.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#148&lt;/td&gt;
&lt;td&gt;The tallest man was 8 ft. 11 in.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#159&lt;/td&gt;
&lt;td&gt;The first TV show ever to be put into reruns was &amp;quot;The Lone Ranger.&amp;quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#??7&lt;/td&gt;
&lt;td&gt;A queen bee can lay 800-1500 eggs per day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#53&lt;/td&gt;
&lt;td&gt;The average woman consumes 6 pounds of lipstick in her lifetime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#163&lt;/td&gt;
&lt;td&gt;The first penny had the motto &amp;quot;Mind your own business.&amp;quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;I've temporarily run out of Snapple, more to come later.&lt;/p&gt;
&lt;p&gt;Thanks to the person who posted all of them (the original 109):&lt;/p&gt;
&lt;p&gt;All of them:
Snapple &amp;quot;REAL FACTS &amp;quot;
Joseph Shamah
&lt;a class="reference external" href="mailto:Mrsomeone2000&amp;#64;aol.com"&gt;Mrsomeone2000&amp;#64;aol.com&lt;/a&gt;&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="7%" /&gt;
&lt;col width="93%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Number&lt;/th&gt;
&lt;th class="head"&gt;Fact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;A Goldfish's attention span is three seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Animals that lay eggs don't have belly buttons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Beavers can hold their breathe for 45 minutes under water&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Slugs have 4 noses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Camels have 3 eyelids&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;A honey bee can fly at 15mph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;A queen bee can lay 800-1500 eggs per day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;A bee has 5 eyes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;The average speed of a housefly is 4.5 mph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Mosquitos are attracted to people who just ate bananas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Flamingos are pink because they eat shrimp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Emus and Kangaroos cannot walk backward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Cats have over 100 vocal chords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Camel's milk does not curdle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;All porcupines float in water&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;The world's termites outweigh the world's humans 10 to 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;A hummingbird weighs less then a penny&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;A jellyfish is 95% water&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;Children grow faster in the spring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Broccoli is the only vegetable that is also a flower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;Almonds are part of the peach family&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;Alaska has the highest percentage of people who walk to work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;The San Francisco Cable cars are th only mobile national monument&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;The state of maine has 62 lighthouses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;The only food that does not spoil is honey&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;The Hawaiian alphabet only has 12 letters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;A ball of glass will bounce higher then a ball of rubber&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;Chewing gum while peeling onions will prevent you from crying&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;On average a human will spend up to 2 weeks kissing in his/her lifetime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;Fish have eyelids&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;The average human will eat an average of 8 spiders while sleeping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;There are one million ants to every human in the world&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;Termites eat through wood two times faster when listening to rock music!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;If you keep a goldfish in a dark room it will eventually turn white&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;Elephants only sleep 2 hours a day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;A duck's quack doesn't echo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;37&lt;/td&gt;
&lt;td&gt;A snail breathes through it's foot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;Fish cough...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;39&lt;/td&gt;
&lt;td&gt;An ant's smell is stronger then a dog's&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;It is possible to lead a cow up stairs but not down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;Shrimp can only swim backward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;Frogs cannot swallow with their eyes open&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;A cat's lower jaw cannot move sideways&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;The bullfrog is the only animal that never sleeps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;Elephants are capable of swimming 20 miles per day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;Elephants are the only mammal that cannot jump&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;47&lt;/td&gt;
&lt;td&gt;Giraffes have no vocal chords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;Cats can hear ultrasound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;Despite its hump...camel's have a straight spine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;Mosquitos have 47 teeth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;51&lt;/td&gt;
&lt;td&gt;There are 63,360 inches in a mile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;52&lt;/td&gt;
&lt;td&gt;11% of people in the world are lefthanded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;53&lt;/td&gt;
&lt;td&gt;The average women consumes 6lbs of lipstick in her lifetime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;54&lt;/td&gt;
&lt;td&gt;The average smell weighs 760 nanograms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;A human brain weighs about 3lbs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;1/4 of the bones in your body are in your feet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;You blink over 10,000,000 times a year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;58&lt;/td&gt;
&lt;td&gt;A sneeze travels out of your nose at 100mph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;Brain waves can be used to power an electric train&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;60&lt;/td&gt;
&lt;td&gt;A tongue is the fastest healing part of the body&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;61&lt;/td&gt;
&lt;td&gt;Pigs get sunburn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;62&lt;/td&gt;
&lt;td&gt;The lifespan of a tastebud is 10 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;63&lt;/td&gt;
&lt;td&gt;The average human produces 10,000 gallons of saliva in a lifetime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;Strawberries contain more Vitamin C then oranges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;A one-day weather forecast requires about 10 billion math calculations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;66&lt;/td&gt;
&lt;td&gt;Americans on average eat 18 acres of pizza a day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;There are 18 different animal shapes in the Animal cracker zoo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;68&lt;/td&gt;
&lt;td&gt;The longest one syllabled word is &amp;quot;screeched&amp;quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;69&lt;/td&gt;
&lt;td&gt;No word in the english language rhymes with month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;70&lt;/td&gt;
&lt;td&gt;A &amp;quot;jiffy&amp;quot; is actually 1/100 of a second (&lt;em&gt;Caller ID is illegal in California&lt;/em&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;71&lt;/td&gt;
&lt;td&gt;There is a town called &amp;quot;Big Ugly&amp;quot; in West Virginia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;72&lt;/td&gt;
&lt;td&gt;The average person uses 150 gallons of water per day for personal use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;73&lt;/td&gt;
&lt;td&gt;The average person spends 2 weeks of it's life waiting for a traffic light to change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;74&lt;/td&gt;
&lt;td&gt;You share your birthday with 9 million others in the world&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;75&lt;/td&gt;
&lt;td&gt;The average person makes 1,140 phone calls per year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;76&lt;/td&gt;
&lt;td&gt;The average person spends 2 years on the phone in his/her lifetime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;77&lt;/td&gt;
&lt;td&gt;No piece of paper can be folded more then 7 times&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;78&lt;/td&gt;
&lt;td&gt;Alaska is the most eastern and western state in the US&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;79&lt;/td&gt;
&lt;td&gt;There are 119 grooves on the edge of a quarter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;About 18% of Animal owners share their bed with their pet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;81&lt;/td&gt;
&lt;td&gt;Alaska has more caribou then people&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;82&lt;/td&gt;
&lt;td&gt;August has the highest percent of births&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;83&lt;/td&gt;
&lt;td&gt;Googol is a number (1 followed by 100 zeros)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;84&lt;/td&gt;
&lt;td&gt;Oysters can change genders back and forth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;85&lt;/td&gt;
&lt;td&gt;The Mona Lisa has no eyebrows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;86&lt;/td&gt;
&lt;td&gt;Until the 19th century solid blocks of tea were used as money in Siberia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;87&lt;/td&gt;
&lt;td&gt;A mile on the ocean and a mile on land are not the same distance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;88&lt;/td&gt;
&lt;td&gt;A ten gallon hat holds less then one gallon of liquid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;89&lt;/td&gt;
&lt;td&gt;The average American walks 18,000 steps a day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;90&lt;/td&gt;
&lt;td&gt;The average raindrop falls at 7mph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;91&lt;/td&gt;
&lt;td&gt;There are more telephones then people in Washington D.C.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;92&lt;/td&gt;
&lt;td&gt;Fish can drown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;93&lt;/td&gt;
&lt;td&gt;A Kangaroo can jump 30 feet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;94&lt;/td&gt;
&lt;td&gt;Lizards communicate by doing push-ups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;95&lt;/td&gt;
&lt;td&gt;Squids can have eyeballs the size of volleyballs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;96&lt;/td&gt;
&lt;td&gt;The average American will eat 35,000 cookies in his/her lifetime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;97&lt;/td&gt;
&lt;td&gt;A turkey can run at 20mph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;98&lt;/td&gt;
&lt;td&gt;When the moon is directly over you, you weigh less&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;99&lt;/td&gt;
&lt;td&gt;You burn 20 calories an hour chewing gum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;In a year, the average person walks 4 miles makeing their bed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;About half of all Americans are on a diet at any given time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;A one-minute kiss burns 26 calories&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Frowning burns more calories then smiling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;There are more then 30,000 diets on public record&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;105&lt;/td&gt;
&lt;td&gt;You will burn 7% more calories walking on hard dirt then pavement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;106&lt;/td&gt;
&lt;td&gt;You way less at the top of a mountain then sea level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;107&lt;/td&gt;
&lt;td&gt;You burn more calories sleeping then watching TV&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;108&lt;/td&gt;
&lt;td&gt;Licking a stamp burns 10 calories&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;109&lt;/td&gt;
&lt;td&gt;Smelling apples and/or bananas can help you loose weight&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Some of these have been changed, according to &lt;a class="reference external" href="http://www.washingtonpost.com/wp-dyn/articles/A51971-2003Jul13.html"&gt;this article&lt;/a&gt;,
if you know the original questions for any of these I'd like to have them. You can
email me at &lt;a class="reference external" href="mailto:snapplefacts&amp;#64;brianlane.com"&gt;snapplefacts&amp;#64;brianlane.com&lt;/a&gt;&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Tue, 15 Jul 2003 00:00:00 -0000</pubDate><category>snapple</category></item><item><title>Linux Fest Northwest 2003</title><link>http://brianlane.com/linux-fest-northwest-2003.html</link><description>&lt;p&gt;For me the day began with at 5am, scrambling to make sure I remembered to bring
everything -- laptop, &lt;a class="reference external" href="http://www.zaurus.com/"&gt;Zaurus&lt;/a&gt;, cat-5 cable,
cellphone, digital camera, USB to serial adapter, camera cable for downloading
pictures (I ought to be able to do that with the Zaurus, shouldn't I?), etc. I
wasn't sure exactly how long it would take me to make it to Bellingham from
Seabeck, but I was pretty sure I needed to catch the 7:10 Kingston to Edmonds
ferry. I made it with 10 mintes to spare, and spent the 30 minute crossing
writing the start of this report. The Zaurus keyboard was particularly handy
since I had dropped my stylus on the floor as I rushed out the door.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_443a7122.jpg" src="images/lfnw2003/lFNW2003_html_443a7122.jpg" /&gt;
&lt;p&gt;I learned later that a couple of other &lt;a class="reference external" href="http://www.kplug.org"&gt;KPLUG&lt;/a&gt; members (former KPLUG President
Shawn Bakker and former Vice-President Ron Tidd -- everyone in KPLUG seems to
be either a current or former officer), were about 50 feet to my right on the
same ferry. We didn't coordinate very successfully this year, but we'll learn.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_b52f19f.jpg" src="images/lfnw2003/lFNW2003_html_b52f19f.jpg" /&gt;
&lt;p&gt;The drive up I-5 was uneventful, passing through Edmonds, Montlake Terrace
(home to &lt;a class="reference external" href="http://www.sea-dmi.com/"&gt;SEA, Inc.&lt;/a&gt;), Everett (home port for a
large part of the Pacific Fleet), Mt. Vernon (site of last year's &lt;a class="reference external" href="/photos/fd2002/"&gt;Wetnet field
day event&lt;/a&gt;) and finally, after about 2 hours and 48 minutes
of travel, to Bellingham. Home to &lt;a class="reference external" href="http://www.wwu.wdu"&gt;Western Washington University&lt;/a&gt;, &lt;a class="reference external" href="http://www.btc.ctc.edu/"&gt;Bellingham Technical College&lt;/a&gt; and the 4th annual &lt;a class="reference external" href="http://www.linuxfestnorthwest.com"&gt;Linux Fest Northwest&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I saw a familiar face right away, David Smead, owner of &lt;a class="reference external" href="http://www.amplepower.com/"&gt;Ample Power&lt;/a&gt;, was getting his portable demo table setup. It
runs off of a couple of batteries and a Trace 800 watt inverter. His company
uses Linux to develop power management systems for boats, Rvs, or just about
anything that runs off a battery. Everything from schematic capture to board
layout and embedded software development is done using Linux.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_m3048bfc4.jpg" src="images/lfnw2003/lFNW2003_html_m3048bfc4.jpg" /&gt;
&lt;p&gt;I had arrived before the official doors opened in order to help setup the KPLUG
booth. Our resident expert on odd hardware, Dennis Parsley, had planned on
bringing some of his systems running Linux -- A Dreamcast, Sun Ultra Sparc and
68k MAC. But he got called in to work at the last second as he was waiting in
line for the ferry. So KPLUG's presence fell from 2 tables to a pile of
business cards. Next year we'll have a backup plan in place. Something that
include cellphones, multiple cars and multiple demo computers.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_6b3910b4.jpg" src="images/lfnw2003/lFNW2003_html_6b3910b4.jpg" /&gt;
&lt;p&gt;Ron &amp;amp; Shawn showed up and we staffed the KPLUG booth just long enough to
realize that something was wrong -- no KPLUG President (who was wisely riding
the &lt;a class="reference external" href="http://www.pogolinux.com"&gt;Pogo Linux&lt;/a&gt; bus), and no Dennis. So we left a
pile of KPLUG business cards and my cat-5 box on the table and headed off to
one of the first lectures of the day, given by &lt;a class="reference external" href="http://bn.bfast.com/booklink/click?sourceid=1160891&amp;amp;amp;ISBN=0764536303"&gt;Red Hat Linux Bible&lt;/a&gt;
author Chris Negus and &lt;a class="reference external" href="http://www.taclug.org"&gt;TACLUG&lt;/a&gt; President Chuck Wolber.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_5669179a.jpg" class="align-right" src="images/lfnw2003/lFNW2003_html_5669179a.jpg" /&gt;
&lt;p&gt;The first lecture was on the upcoming book 'Linux Toys', they are putting
together instructions on how to build fun projects with Linux. One example is
using the &lt;a class="reference external" href="http://x.mame.net/"&gt;xmame&lt;/a&gt; emulator to play old console arcade
games like 1942. After Chuck figured out the joystick was unplugged things went
smoothly. They also have a jukebox project where you can insert a CD, it will
rip it to &lt;a class="reference external" href="http://www.xiph.org/"&gt;Ogg Vorbis&lt;/a&gt; format and save it to harddrive,
and then randomly play all the songs in a continuous loop. Another project is a
remote controlled car that is conneted to a Linux system using a &lt;a class="reference external" href="http://www.smarthome.com/1154.html"&gt;LynX-port&lt;/a&gt; relay control board. A home-built
Digital TV Recorder is also in the works.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_m487cc03.jpg" class="align-left" src="images/lfnw2003/lFNW2003_html_m487cc03.jpg" /&gt;
&lt;p&gt;We then wandered around, checking out the variety of booths. The guys from
&lt;a class="reference external" href="http://www.pogolinux.com"&gt;Pogo Linux&lt;/a&gt; were very knowledgeable and had a RAID system running with 12
120Gig Serial ATA drives. This system was room temperature to the touch, and
only costs $8k! Configured as a RAID5 you would have 11 x 120Gig or
1.3TERAbytes of storage. Zowie! That's a lot of storage (and a lot of stuff to
backup, so you better buy two of them). The only concern I would have about the
system is that the Serial ATA connectors don't appear to have a positive
locking system. Not that a rackmount server is going to see a lot of movement
until the next NW earthquake.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_7ff38f20.jpg" class="align-right" src="images/lfnw2003/lFNW2003_html_7ff38f20.jpg" /&gt;
&lt;p&gt;The keynote speaker for the event was &lt;a class="reference external" href="http://www.li.org/who/bio.php?name=hall"&gt;Jon 'Maddog' Hall&lt;/a&gt;, from &lt;a class="reference external" href="http://www.li.org/"&gt;Linux International&lt;/a&gt;. He was introduced by president of BTC, who seemed a bit
overwhelmed by this year's turnout for the event. The room was packed, I
estimated at least 200 people were sitting and standing in the room, and the
exhibit hall looked like it was still packed as well.&lt;/p&gt;
&lt;p&gt;Maddog talked about approaches to selling Open Source to the business,
governments and educators. He gave his presentation using Star Office, and did
an excellent job of explaining Open Source and how it can help companies and
institutions by giving them control over the software they are using. One of
his examples was a Brazillian company that used Open Source to replace an
outrageously expensive piece of software (1Million per seat) and was able to
stay in business and employ 19 people. In addition to staying in business they
were able to customize the software to their needs, and fix problems quickly
when they arose.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_m2c017489.jpg" class="align-left" src="images/lfnw2003/lFNW2003_html_m2c017489.jpg" /&gt;
&lt;p&gt;There was very little mention of Microsoft, which is appropriate. Open Source
and Linux stand on their own merits, not as an anti-Microsoft system. Maddog
did point out that Microsoft is trying to embrace Open Source in their own
twisted way (my words). Their shared source initiative allows select groups to
view the source to windows via a Microsoft controlled interface. As I pointed
out when talking to Maddog later, it doesn't really matter how much you can
look at it if &lt;em&gt;you can't compile it!&lt;/em&gt; I don't think shared source is
anything to worry about.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_m2b34cdb0.jpg" class="align-right" src="images/lfnw2003/lFNW2003_html_m2b34cdb0.jpg" /&gt;
&lt;p&gt;Dr. Crispin Cowan of &lt;a class="reference external" href="http://www.immunix.com/"&gt;Immunix&lt;/a&gt; gave a
talk that covered the enhanced kernel that Immunix has developed.
They have built custom kernel extensions to protect against stack
overflows, race attacks, printf format string vulnerabilities and a
system that limits what user level applications can access on the
system (a fine-grained chroot enviornment without having to duplicate
all the system libraries and utilities). He also talked about the
coolest game since Pong. Its called Capture The Flag, and its played
at the annual &lt;a class="reference external" href="http://www.defcon.org/"&gt;DefCon&lt;/a&gt; security
convention in Nevada. Players attempt to keep their server up and
running (a scoring system polls the services on the players box,
adding or subtracting points based on the responses it sees), while
attacking other player's systems and attempting to plant their 'flag'
on the other systems. Last year's game was designed by Seattle's own
&lt;a class="reference external" href="http://www.ghettohackers.com/rootfu/"&gt;Ghetto Hackers&lt;/a&gt;.
This looks like a blast, and I may try to put together a regional
event for those who can't make it to DefCon.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_m23f378c6.jpg" class="align-right" src="images/lfnw2003/lFNW2003_html_m23f378c6.jpg" /&gt;
&lt;p&gt;KPLUG's Vice President Rikke Giles gave a tutorial on getting started with
GLADE, which is a library that takes the grunt work out of designing user
interface with GTK. She covered the basics of getting a simple GLADE framework
created. I missed most of the tutorial since I got hungry and went in search of
food. &lt;a class="reference external" href="http://www.kplug.org/glade_tutorial/"&gt;Here's a copy&lt;/a&gt; of the tutorial
she gave earlier this year.&lt;/p&gt;
&lt;p&gt;One of the few problems with the fest was the lack of food. There was an
espresso/pastry stand, and there were hotdogs available for a while but I
missed out and they were closed by the time I went in search of food. My other
problem was that I kept running into people to talk to, and none of them were
in a food line.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_3753f90.jpg" class="align-left" src="images/lfnw2003/lFNW2003_html_3753f90.jpg" /&gt;
&lt;p&gt;The turnout was what I expected, huge! My gauge for such event is 'will I go?'
If it can manage to get me to drive 3 hours each way then there are probably a
bunch of other people who are going to show. Using the door prize tickets as an
estimate there were somewhere around 1000 people who showed up to see what
Linux Fest was all about. The layout of the fest was in a triangle pattern,
with tables on the outside walls and tables in the center in the same shape.
This worked out pretty well I think, giving enough room for people to mill
around and still move past those who had paused to chat with the exhibitors.&lt;/p&gt;
&lt;img alt="images/lfnw2003/lFNW2003_html_m1d66b379.jpg" class="align-right" src="images/lfnw2003/lFNW2003_html_m1d66b379.jpg" /&gt;
&lt;p&gt;There was a wide variety of tables to explore. I meant to go around and take
pictures of all of them, but didn't get the chance (lack of nutrients may hav
also has something to do with this oversite). But there were OpenBSD
demonstrations -- a OpenBSD based T1 router, Ample Power's power management
modules, an 802.11 access point on Soekeris(sp?) board. Python and Perl
Tutorials and teachers, a Chinese Desktop, 60% off Linux books (no O'Rielly
books though), Linux-ware (clothes), TiVO hacking (I really regret missing that
one), book signings by Chris Negus and Illiad, and tons of Raffle items -- SCO,
Red Hat, SuSE, DigiTemp, Tuxes, etc. Whew! Next year I promise to take more
pictures.&lt;/p&gt;
&lt;p&gt;At the end of the show I was able to talk to Maddog Hall a bit. He is also
godfather to Linus's two children, so he gets to see Linus socially when they
are in the same town (Maddog lives in New Hampshire and Linus is in
California). One time when he was out with Linus an enthusiastic Linux user
recognized Maddog (how could you miss him with that distinctive beard!) and
started to tell him how much he loves Linux, Not realizing who Linus was until
Maddog said 'Well, then you probably want to talk to this guy', leaving the
Linux user speechless when he realized who Linus was.&lt;/p&gt;
&lt;p&gt;The Fest was a great success. I'd like to thank everyone who helped put it on,
especially the guys at &lt;a class="reference external" href="http://www.blug.org"&gt;BLUG&lt;/a&gt; (Bellingham Linux User Group). There is some talk
on the mailing list of trying to move it to a more central  location, but I
think anyone will have trouble putting together the set of skill and services
provided by BTC and BLUG. I'm looking forward to next year already. Now if we
can just get Linus to take a little drive north next year...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Thu, 01 May 2003 00:00:00 -0000</pubDate><category>Linux</category><category>Linuxfest</category><category>Bellingham</category><category>KPLUG</category><category>TACLUG</category><category>BLUG</category></item><item><title>Olympic Arms Phoenix Rising Event</title><link>http://brianlane.com/olympic-arms-phoenix-rising-event.html</link><description>&lt;p&gt;&lt;strong&gt;UPDATE 11/17/2001&lt;/strong&gt; I'm a bit tardy in this update, the new
Olympic Arms building is done and open for business. I haven't had
the chance to make it down myself.&lt;/p&gt;
&lt;p&gt;I am lucky enough to live about an hour away from &lt;a class="reference external" href="http://www.olyarms.com"&gt;Olympic Arms&lt;/a&gt; in Olympia,
Washington. They are manufacturers of a variety of weapons and kits, most
famously for their highly accurate AR-15 rifles.&lt;/p&gt;
&lt;p&gt;On June 7, 2000 a bearing in an exhaust fan seized and the resulting fire
destroyed their sales and shipping building. Luckily the manufacturing
buildings were not touched.&lt;/p&gt;
&lt;p&gt;To thank all of their customers for their support they put together the Phoenix
Rising event this weekend (Sept. 16, 2000). I attended the day's activities,
and had a blast!&lt;/p&gt;
&lt;p&gt;I woke up early and jumped into my truck to head off for a day of fun and
guns. According to Yahoo's driving directions it would take me over an hour
and a half to get there, and the tour of the factory was going to start at
9am. As with all the best laid plans, this isn't quite how it worked out.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/arrive_large.jpg"&gt;&lt;img alt="Arriving at the Olympic Arms Factory" class="align-left" src="images/phoenix_rising/arrive_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;I got there early (about 8am) and the parking lot was already filling up
with people. They had initially expected only 50 or 100 people to respond,
but over 200 had RSVPed their announcements of the event.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/tomtime_large.jpg"&gt;&lt;img alt="images/phoenix_rising/tomtime_small.jpg" class="align-right" src="images/phoenix_rising/tomtime_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Tom Spithaler did a great job of getting things organized in the face of
the overwhelming response, and tour groups of about 25 people each started
making their way through the plant right away.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/olycrew_large.jpg"&gt;&lt;img alt="images/phoenix_rising/olycrew_small.jpg" class="align-left" src="images/phoenix_rising/olycrew_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Dan Brennan, Owner Bob Schuetz, and Tom Spithaler give us some background
on the company and welcome us to Olympic Arms.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/newshipping_large.jpg"&gt;&lt;img alt="images/phoenix_rising/newshipping_small.jpg" src="images/phoenix_rising/newshipping_small.jpg" /&gt;&lt;/a&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/rack_large.jpg"&gt;&lt;img alt="images/phoenix_rising/rack_small.jpg" src="images/phoenix_rising/rack_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;The tour starts out with their new, much smaller, shipping room. Racks of
parts in bins are crammed into every corner of the room, with a rack of
complete AR-15s up against one wall.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/rawbarrels_large.jpg"&gt;&lt;img alt="images/phoenix_rising/rawbarrels_small.jpg" class="align-right" src="images/phoenix_rising/rawbarrels_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;We move on to the barrel manufacturing process. Photos were limited in the
manufacturing areas, for security reasons. You can read more about their
barrels at the Olympic Arms &lt;a class="reference external" href="http://www.olyarms.com/index.php?option=com_content&amp;amp;task=view&amp;amp;id=27&amp;amp;Itemid=43"&gt;barrel info&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;The tour continues through the complete manufacturing process for the AR-15s
and their Safari Arms .45 pistols. They take raw castings (or forgings) from
their casting house in California and machine them into the  precision
weapons that we all love to shoot.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/rawuppers_large.jpg"&gt;&lt;img alt="images/phoenix_rising/rawuppers_small.jpg" class="align-left" src="images/phoenix_rising/rawuppers_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Here are what the upper receivers look like before being machined into their
final state.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/rawlowers_large.jpg"&gt;&lt;img alt="images/phoenix_rising/rawlowers_small.jpg" class="align-right" src="images/phoenix_rising/rawlowers_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;And here are what raw lowers look like.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/morebarrels_large.jpg"&gt;&lt;img alt="images/phoenix_rising/morebarrels_small.jpg" class="align-left" src="images/phoenix_rising/morebarrels_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Here are more barrels of barrels, closer to being finished.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/shavings_large.jpg"&gt;&lt;img alt="images/phoenix_rising/shavings_small.jpg" class="align-right" src="images/phoenix_rising/shavings_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;A pile of aluminum shavings, ready to be recycled.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/fnrack_large.jpg"&gt;&lt;img alt="images/phoenix_rising/fnrack_small.jpg" class="align-left" src="images/phoenix_rising/fnrack_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Olympic arms had started producing lower receivers for FN-FAL rifles.
They are also experimenting with complete rifles, a couple of which could
be found on racks. &lt;em&gt;UPDATE:&lt;/em&gt; It looks like they aren't doing the FN
receivers anymore, I can't find any mention of it on their current (2005)
website.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/45pistols_large.jpg"&gt;&lt;img alt="images/phoenix_rising/45pistols_small.jpg" class="align-right" src="images/phoenix_rising/45pistols_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Safari Arms .45 pistols are manufactured by Olympic Arms, before the tour
I hadn't realized that they made complete pistols. They are a bit out of my
price range, but you get what you pay for!&lt;/p&gt;
&lt;p&gt;The fire damage to their sales and shipping building is impressive and
sobering. Its quite a feeling to look at the destruction and realize that
nature can wipe out everything you've worked for in an instant. Carpe Diem!&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/firedamage1_large.jpg"&gt;&lt;img alt="images/phoenix_rising/firedamage1_small.jpg" src="images/phoenix_rising/firedamage1_small.jpg" /&gt;&lt;/a&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/firedamage2_large.jpg"&gt;&lt;img alt="images/phoenix_rising/firedamage2_small.jpg" src="images/phoenix_rising/firedamage2_small.jpg" /&gt;&lt;/a&gt;
&lt;img alt="images/phoenix_rising/evergreen_large.jpg" class="align-center" src="images/phoenix_rising/evergreen_large.jpg" /&gt;
&lt;p&gt;After the tour we caravaned over to the Evergreen Sportsman's Club (a web
link would be appreciated, I couldn't find one). This place is huge! The
have camping space, skeet, trap, etc. ranges as far as the eye can see, and
who knows how many rifle and pistol ranges hidden back in the woods. They
were generous in their donation of their facilities to Olympic arms for
free! Thanks guys!&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/howto_large.jpg"&gt;&lt;img alt="images/phoenix_rising/howto_small.jpg" class="align-left" src="images/phoenix_rising/howto_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;At the range they setup a number of weapons for people to shoot, including a
PCR-97 that their Master Gunsmith Steve (?) built on site with everyone
watching.&lt;/p&gt;
&lt;p&gt;This gun was raffled off at the end of the day with the proceeds going to the
Evergreen Sportsman's club. Ironically a reporter from &lt;a class="reference external" href="http://www.sofmag.com"&gt;Soldier of Fortune&lt;/a&gt; was there to report on the event, and she ended up
winning the rifle!&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/questions_large.jpg"&gt;&lt;img alt="images/phoenix_rising/questions_small.jpg" class="align-right" src="images/phoenix_rising/questions_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Tom Spithaler was available to answer general questions from the group and hand
out the last of their supply of 2000 catalogs.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/static/images/phoenix_rising/durachrome_large.jpg"&gt;&lt;img alt="images/phoenix_rising/durachrome_small.jpg" class="align-left" src="images/phoenix_rising/durachrome_small.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;A thousand rounds of ammo and a number of rifles, including their new
Durachrome rifle, were setup for people to try out. A fun time was had by all!&lt;/p&gt;
&lt;p&gt;They also roasted two pigs for everyone to eat (It tasted great, I've never
had roasted pig before). Most of the day was spent shooting and
hanging around waiting for the raffle items to be drawn. I regret now not
having shot any of their Durachrome rifles, but the line was pretty long
and I was having fun BSing with the other guys from the
&lt;a class="reference external" href="http://www.ar15.com"&gt;ar15.com&lt;/a&gt; forums.&lt;/p&gt;
&lt;p&gt;I'd like to thank Olympic Arms for putting on this event and for making such
high quality products at reasonable cost.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Sat, 16 Sep 2000 00:00:00 -0000</pubDate><category>Olympic Arms</category><category>AR-15</category><category>Guns</category><category>Phoenix Rising</category></item><item><title>Build an AR-15 Rifle</title><link>http://brianlane.com/build-an-ar-15-rifle.html</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#parts" id="id1"&gt;Parts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#build" id="id2"&gt;Build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#problems" id="id3"&gt;Problems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#range-report" id="id4"&gt;Range Report&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;This HOWTO was written in 2000. Since then the prices on bare lowers has gone
up a little and the 'assault weapons' ban has expired. I'd like to dedicate
this page to the memory of my friend &lt;a class="reference external" href="http://www.kplug.org/~mhjack"&gt;Mike Jackson&lt;/a&gt; who died in March 2003. His enthusiasm for the
AR-15 is what convinced me to build my own and write this article.&lt;/p&gt;
&lt;p&gt;After 3 months of waiting I finally received my &lt;a class="reference external" href="http://www.m-aparts.com"&gt;M&amp;amp;A Parts&lt;/a&gt;
C.A.R. 16&amp;quot; rifle kit. But they shipped it with the
collapsible CAR stock, not the A2 stock that I ordered, so I can't finish
building the rifle yet. I cannot use the CAR stock for a couple of reasons --
One is that I don't like them, and the second is that this is a &lt;a class="reference external" href="http://www.ar15.com/content/legal/preORpost.html"&gt;Post Ban&lt;/a&gt; rifle, so the US
Government, under the divine guidance of Bill Clinton, has deemed it to be
illegal for you to put a collapsible stock on a post-ban weapon (at least until
the 'Assault Weapon' ban sunsets in October 2004).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Building the AR-15 rifle&lt;/strong&gt;
Copyright 2005-2012 by Brian C. Lane
All Rights Reserved&lt;/p&gt;
&lt;div class="section" id="parts"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Parts&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;em&gt;$120&lt;/em&gt; - &lt;a class="reference external" href="http://www.olyarms.com"&gt;Olympic Arms&lt;/a&gt; PCR-99 stripped lower receiver&lt;/li&gt;
&lt;li&gt;&lt;em&gt;$401&lt;/em&gt; - &lt;a class="reference external" href="http://www.m-aparts.com"&gt;M&amp;amp;A Parts&lt;/a&gt; Post-Ban CAR 16&amp;quot; Kit&lt;/li&gt;
&lt;li&gt;&lt;em&gt;$50&lt;/em&gt; - Misc. tools from &lt;a class="reference external" href="http://www.brownells.com"&gt;Brownells&lt;/a&gt;
including the pivot pin install and removal tools and roll pin punches and
holders. Also the bolt catch removal tool is handy for holding things in
place while installing the bolt catch&lt;/li&gt;
&lt;li&gt;&lt;em&gt;$570&lt;/em&gt; - Total&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;I actually bought more tools than I needed. What I really used were the roll
pin punches and roll pin holders, the pivot pin install and removal tools. I
also used a light hammer, block of wood, some cloth to protect the lower
from scratches and a screwdriver. Some people say that you can build it
without the roll pin punches and holders, but personally I wouldn't
recommend it. Having the right tools for the job goes a long way towards
making life easier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here are all the pieces and the Brownells tools&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="images/ar15/ar15-parts.jpg" src="images/ar15/ar15-parts.jpg" /&gt;
&lt;/div&gt;
&lt;div class="section" id="build"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Build&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I put together the lower using the instructions from &lt;a class="reference external" href="http://www.ar15.com/content/guides/"&gt;ar15.com&lt;/a&gt;, which is an excellent informaiton
source.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="problems"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Problems&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The disconnector spring (the one that is wider at one end) would not fit
into my trigger assembly at all, so I had to squeeze the end of it a little
bit. You want to make sure that the spring will still function when you do
this. It should fit into the trigger assembly tightly at the bottom, leaving
the top to be compressed by the disconnector without catching on anything.&lt;/li&gt;
&lt;li&gt;I installed the take down pin detent backwards (I think). I installed it
with the pointy side towards the take-down pin which has a couple of holes
machined into the groove to catch the detent and prevent the pin from falling
out. But with the pointed side up, I couldn't get the pivot pin to move
without patting it with a hammer and piece of wood. I removed it (using a
pivot pin detent removal tool, which I luckily bought from
&lt;a class="reference external" href="http://www.brownells.com"&gt;Brownells&lt;/a&gt; along with my other tools.
I reinstalled it with the pointed end towards the spring and it works much
better.&lt;/li&gt;
&lt;li&gt;The safety selector would not fit smoothly. It was hanging up on the
back of the trigger assembly, which was just barely visible when looking
through the safety selector hole. I gave it a couple of taps with the hammer
and a block of wood and it slid into place. &lt;em&gt;But that was the wrong way to do
it.&lt;/em&gt; I should have removed the hammer and trigger assembly and put in the
selector at the same time that I put in the trigger assembly. Live and
learn.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Assembled lower receiver&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="images/ar15/ar15-lower.jpg" src="images/ar15/ar15-lower.jpg" /&gt;
&lt;p&gt;I also have a problem with the upper and lower not fitting together quite
right. It seems that the lower must have a slight bump right behind where
the forward assist is on the upper because I can't get the take down pin to
fit without pushing them together pretty hard. I think I'll sand off the
lower at that point until it fits, but I'm still thinking about it.&lt;/p&gt;
&lt;p&gt;According to the guys over on &lt;a class="reference external" href="http://www.ar15.com"&gt;ar15&lt;/a&gt;
a tight fit between the upper and lower is normal and will probably go away
after I put a couple of hundred rounds through it, so I'm not going to worry
about it for now.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;UPDATE:&lt;/em&gt; Sure enough, after fitting everything together and working the
takedown and pivot pins back-n-forth a few times everything seems to fit
together pretty well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Assembled rifle, waiting for its stock&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="images/ar15/ar15-nostock.jpg" src="images/ar15/ar15-nostock.jpg" /&gt;
&lt;/div&gt;
&lt;div class="section" id="range-report"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Range Report&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;UPDATE:&lt;/em&gt; I got the stock (thanks to &lt;a class="reference external" href="http://www.m-aparts.com"&gt;M&amp;amp;A Parts&lt;/a&gt; for getting it shipped out so
quickly). I took it to the range this weekend. On the first day out I ran into
magazine feed problems, the 2nd to last round wasn't feeding on 2 of my mags.
The 3rd one worked fine. I used some mixed ammo I got from a friends
(Winchester, Remington) and it worked great. A couple of rounds of the cheap
Russian ammo I picked up at the last gunshow misfired - 4 out of about 200
rounds so far. &lt;strong&gt;NOTE:&lt;/strong&gt; Do not use the cheap ammo with the lacquer finish on
it (Wolf is one manufacturer of this), the finish will melt in the chamber and
cause feed problems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Assembled with A2 stock and 20rd magazine&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="images/ar15/ar15-20rd.jpg" src="images/ar15/ar15-20rd.jpg" /&gt;
&lt;p&gt;The sights were off, it was shooting high at 25 yards, but I didn't know how to
adjust the front sight, so I called it a day after firing about 100 rounds
through it. On Sunday I went back, after having learned how to move the front
sight up and down (use a bullet tip to depress the little pin and rotate it
counter clockwise to lower the point of aim). Just by chance I got it adjusted
right on. The first group on Sunday looked like the picture below! Now I just
need to learn how to shoot tighter groups.&lt;/p&gt;
&lt;p&gt;I also fixed the mag problem, I think, I bent the right lip slightly so that
the base of the righthand stack was a little higher than before, so the bolt
will catch and strip it off consistently. It seemed to work, I put another 200
rounds through it Sunday without a problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;First 3 shots (&amp;#64; 25yards)&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="images/ar15/firstshots.jpg" src="images/ar15/firstshots.jpg" /&gt;
&lt;p&gt;&lt;em&gt;UPDATE 11/16/2002&lt;/em&gt; The mags continued to plague me until the next gunshow
where I picked up a bunch of military surplus mags (Universal, OKay, Colt).
Those cheap steel mags are totally unreliable. I use surplus mags with metal
followers and have only had problems with the 1 Colt magazine that I picked up.
I haven't paid more than $15 for any of them and they all work great.&lt;/p&gt;
&lt;p&gt;Since building this one I have built another, using a cast lower receiver from
&lt;a class="reference external" href="http://www.olyarms.com"&gt;Olympic Arms&lt;/a&gt;. I didn't have any real problems other than the hole in the
grip not lining up properly (I reamed out the grip hole and it fit). But the
cast lowers just feel cheap. Their finish is rough and they feel brittle.
They're probably just as good as forged, but I'll stick with the ones with a
better look to them -- those cheap Plinker AR-15s that &lt;a class="reference external" href="http://www.olyarms.com"&gt;Olympic Arms&lt;/a&gt; is
making now are really ugly, with cast upper and lower parts.&lt;/p&gt;
&lt;p&gt;I built a 3rd from the forged lower built in this article and a flattop
&lt;a class="reference external" href="http://www.olyarms.com"&gt;Olympic Arms&lt;/a&gt; upper that I bought at their Phoenix Rising event. It really
isn't building when all you do it put a new upper on the lower, but it fit just
fine and works great with a Leupould 3-9x40mm scope on it, or a &lt;a class="reference external" href="http://www.bushnell.com/products/riflescopes/holosight.html"&gt;Bushnell
Holosight&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Tue, 01 Feb 2000 00:00:00 -0000</pubDate><category>AR-15</category><category>Guns</category><category>DIY</category></item><item><title>XfreeCD audio CD player</title><link>http://brianlane.com/xfreecd.html</link><description>&lt;img alt="XfreeCD screenshot" src="images/xfreecd/xfreecd.gif" /&gt;
&lt;p&gt;XfreeCD was one of my first Linux projects, it is a audio CD player application
that takes its visual design from Nate Smith's &lt;a class="reference external" href="http://www.geocities.com/SiliconValley/Pines/9226/"&gt;freeCD&lt;/a&gt;. Development of XfreeCD
stalled when I switched to using &lt;a class="reference external" href="http://www.xmms.org/"&gt;xmms&lt;/a&gt; to play all my
music after ripping all of it it to ogg format using &lt;a class="reference external" href="http://www.nostatic.org/grip/"&gt;Grip&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Current development has been moved to &lt;a class="reference external" href="http://xfreecd.sf.net"&gt;a Source Forge project&lt;/a&gt;. Check there for the latest versions.&lt;/p&gt;
&lt;p&gt;XFreeCD features a simple, borderless playback interface, CDDB song database
support, GTK+. My source does not compile with the newer versions of GTK+ and
the interface to play CDs has probably changed since it was last updated.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Old Releases&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="/static/downloads/xfreecd/"&gt;Browse the previous releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bcl</dc:creator><pubDate>Wed, 02 Dec 1998 00:00:00 -0000</pubDate><category>X</category><category>CD Player</category></item></channel></rss>
