Wednesday, December 24, 2008

Cleaning out grinder in Solis 5000

Okay, so i enjoy a good cup of espresso or coffee. Our Solis 5000 needs its grinder cleaned about once a year or it takes longer and longer to complete the grind. Here's what i do. There are two screws that hold the coffee hopper on, a philips in back and a Torx 15 in the front. Make note of where the grind dial is (12 in this case) as you'll need to set it back there when you put the hopper back on.
This is what you'll see.
Remove the flexible rubber bean guide and make note of where the red index mark is on the outer retaining ring. Three o'clock in this case. Now, rotate the outer ring until it's a little past the twelve o'clock position. This frees the inner part. You'll now see this.
Clean all the old grinds out; i use a dustbuster. Now you'll have this.
Reassemble by putting the inner part back in, rotating the outer dial to where it was before, replacing the flexible bean guide, and then the hopper with the grind dial set to where it was before. You should be good for another year or so.

As always, do this at your own risk, and take pictures at each step so you know where things started.

I also run about two cups of vinegar from the water reservoir out the steam wand via opening the steam valve that produces hot water.  This in addition to Solistabs of course.  Both of these enhance the espresso...

Monday, December 22, 2008

Planned Obsolesence

I had been using this timer to run two watch winders for several years when it crapped out. I like it as it has two outlets and did exactly what i wanted it to do. So, i opened it up expecting to find a soldered in dead battery (manufacturers typically don't want to spend the money on AC/DC converters in their products) and there it was: a 2032 @ ~1v. Strangely, it wasn't soldered, but crimped so that two metal spikes where driven into the battery on each side. Had to pry them off, and then i soldered a new battery in as i don't have a tool that will do such a cramp. See illustration, the original battery is the yellow circle.

Tuesday, December 9, 2008

Making a bootable USB BT3 from the live CD

Backtrack 3 (http://www.remote-exploit.org/backtrack.html) has a download for a USB device, but i was able to create a bootable USB thumb drive from the live CD itself:
umount /dev/sda1
mkfs.vfat /dev/sda1
mount /dev/sda1
mount /dev/hdc /mnt/cd
cp -r /mnt/cd/* /mnt/sda1
cd /mnt/sda1/boot
./bootinst.sh
The thumb drive then worked; it is slower than the live CD, but one can save files etc. to it.

Friday, December 5, 2008

Cookie file in Firefox 3

Looks like Firefox 3 is using sqlite3 to store cookies. To see your saved cookies is OSX, do:
sqlite3 ~/Library/Application\ Support/Firefox/Profiles/*.default/cookies.sqlite '.dump'
and under Linux do:
sqlite3 ~/.mozilla/firefox/*.default/cookies.sqlite '.dump'
Later, i found http://blogs.igalia.com/dpino/?cat=6 with a lot more good info...

Thursday, December 4, 2008

A rather cryptic Java SAX XML error

So, i received this error "The processing instruction target matching "[xX][mM][lL]" is not allowed." from an rss feed using JRSST. Not the most transparent message ever. I found by Googling that this means '<' wasn't the very first character in the file. Sure enough. So here's the Java i wrote to get around this (assuming you already have an InputStream from URL openConnection and connect):
PushbackInputStream pbis = new PushbackInputStream (inputstream);

int c;
while ((c = pbis.read()) != '<') {}

pbis.unread (c);

inputsource = new InputSource (pbis);

Tuesday, December 2, 2008

Replacement part for Solis 5000

So we have this great Solis Master 5000 super automatic espresso machine. The plastic steamer thingy took it's own life via the disposal recently. Called Solis service http://www.soliscoffee.com/ which is actually Empire Fulfillment http://www.empirefulfillment.com/ and they said the Gaggia Pannarello Wand is the one that fits. Went to http://www.wholelattelove.com and ordered same. A bit complicated, but the 'net still came through...

Followup. The part came in and i'm disappointed. It "fits" i guess, but extends too far down. The original went all the way up to the knurled region and did not extend much beyond the end of the wand. The replacement is pretty much useless as fitting anything under it is impossible. Not a huge deal as i can simply use the steam wand by itself, but nonetheless...

Necessary firefox addons

Foxmarks Bookmark Synchronizer

Saturday, November 29, 2008

Rails conventions

Models (and therefore the underlying classes they create) are capitalized and singular. Each creates a table that is lower-cased and plural.
 ./script/generate scaffold Student name:string
rake db:migrate
Looking at db/schema.rb shows:
ActiveRecord::Schema.define(:version => 20081129213933) do

create_table "students", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

end
The views and controllers are plural: app/views/students and app/controllers/students_controller.rb, but the model is singular: app/models/student.rb. Remember there is a hidden "id" field in each row of each table so don't create your own "student_id" field.

And from http://itsignals.cascadia.com.au/?p=7
Model Naming Convention

Table: orders
Class: Order
File: /app/models/order.rb
Primary Key: id
Foreign Key: customer_id
Link Tables: items_orders

Controller Naming Convention

Class: OrdersController
File: /app/controllers/orders_controller.rb
Layout: /app/layouts/orders.html.erb

View Naming Convention

Helper: /app/helpers/orders_helper.rb
Helper Module: OrdersHelper
Views: /app/views/orders/… (list.html.erb for example)

Blogging

I've been blogging for five years now. When i started, i didn't like any of the extant software so did what i do too often and wrote my own. I migrated to geeklog, and now here. I'll be posting some of the more relevant bits from the previous ones here as time goes by...

Bodum Santos/Pebo


I have a stovetop Bodum Santos (now Pebo) and like it. Its tons of fun at parties. Its best to use a course grind, and importantly to allow the brewing to take one minute. That is, after the water is in the top, turn down the heat but don't turn it off until the top has churned for a minute. This helps a lot when the coffee is "vacuumed" back down. Otherwise, the filter clogs easily. I do wish Bodum would come back out with their electric version, especially the smaller of the two versions...

Friday, November 21, 2008

Bash menu script

I long had a csh script that reads a '.choices' file in each directory, display the choices, and execute my choice. Well, i've migrated away from csh and no longer have it on many of my machines. So, i wrote the following:
#! /bin/bash -e

filename=".choices"

if [ "$1" == "-f" ]
then
    filename="$2"
    shift
    shift
elif [ ! -r $filename ]
then
    prefix=.
    while true
    do
        absolute=$(cd $prefix; pwd)

        if [ -r $absolute/$filename ]
        then
            filename=$absolute/$filename
            break
        fi

        if [ $absolute = "/" ]
        then
            echo "No .choices file found, exiting"
            exit 1
        fi

        prefix=$prefix/..
    done
fi

if [ "$1" != "" ]
then
    a=$1
    shift
    echo `sed -ne "$a,$a p" $filename` $*
    eval `sed -ne "$a,$a p" $filename` $*
    exit
fi

IFS=$'\n'

select CHOICE in `cat $filename`
do
    eval $CHOICE $*
    break
done
 

This wasn't as easy as it looks. Getting bash to create a single word for the select statement from lines in a file. Finding the right incantation for the IFS was the tricky part...

Thursday, November 20, 2008

Ubuntu live usb

Downloaded and installed the .deb from http://klik.atekon.de/liveusb/. Mounted via loop a distribution i had around:
sudo mount -o loop Desktop/ubuntu-8.04.1-desktop-i386.iso /cdrom
Ran 'liveusb' and it worked. Love that ubuntu...

Wednesday, November 19, 2008

Rails on Linux

yum install ruby
yum install ruby-devel
yum install rubygems
gem install rails
gem install mongrel
gem install sqlite3-ruby

Thursday, November 13, 2008

Broken Brother paper folder

I'm an gadget guy. Bought a cheap Brother paper folder a couple of years ago and recently it started eating paper instead of folding it. So, i torn it apart. Sure enough, the "rubber bands" that hold everything together had disintegrated. Happily, i had some electrical cable ties that fit. Works again. Here's a cheesy cell phone photo that shows the rubber bands and the new cable ties:

Trials with a Garmin eTrex Legend

I've had a Garmin eTrex Legend for quite a while now. It started acting quite flaky: powering down randomly, not displaying all the pixels, etc. Apparently I not alone in this. Found distructions at http://users.tpg.com.au/benj2005/gps/inside_etrex.htm and being who I am, went for it. Much better afterward. Then I wanted to upgrade the software and keep it updated. This has turned in to a much bigger pain. Was able to use the serial connection and a Windows machine to do the upgrade, but I don't do Windows very often and want to use one of my Macs. IOGear GUC232A USB->serial cable. Again, works with Windows, but not OSX 10.4. Grabbed the driver from http://sourceforge.net/projects/osx-pl2303/. The IOGear is recognized:

Steve-Beatys-Computer:~ beaty$ ls -l /dev/tty.*
crw-rw-rw- 1 root wheel 11, 2 Oct 2 14:33 /dev/tty.Bluetooth-Modem
crw-rw-rw- 1 root wheel 11, 0 Oct 2 14:33 /dev/tty.Bluetooth-PDA-Sync
crw-rw-rw- 1 root wheel 11, 10 Oct 4 08:33 /dev/tty.PL2303-0000103D

and I can connect to it via 'screen' and make the LED flash, but Garmin's WebUpdate doesn't see it. So it looks like i'll have to find a

Wednesday, November 12, 2008

Mounting a NTFS image in Linux using loop

I had a binary image, created by dd (its important to grab the whole disk, not just one partition):
dd bs=1M if=/dev/sdd of=tag1.bin
of a disk drive from a Windows box that i wanted to explore in Linux. Looking at the file gives:
$ file tag1.bin
tag1.bin: x86 boot sector, Microsoft Windows XP MBR, Serial 0xe475e475
With some help from http://jonmccune.wordpress.com/virtualization-stuff/ i did:
/sbin/fdisk tag1.bin
You must set cylinders.
You can do this from the extra functions menu.

Command (m for help): x

Expert command (m for help): p

Disk tag1.bin: 255 heads, 63 sectors, 0 cylinders

Nr AF  Hd Sec  Cyl  Hd Sec  Cyl     Start      Size ID
1 80   1   1    0 254  63 1019         63   16386237 07
2 00   0   0    0   0   0    0          0          0 00
3 00   0   0    0   0   0    0          0          0 00
4 00   0   0    0   0   0    0          0          0 00

The interesting bit is the "Start" column, which is where the first partition starts. One multiples by the sector size (512) to arrive at:
mount -o loop,offset=32256 tag1.bin /tmp/mount/

Tuesday, November 11, 2008

Headphones

I usually listen to music in headphones and i seem to have a decent set of ears, so sound quality means a lot. One cannot beat the audio-technica ATH-AD700 for the money. I found mine for ~$115 and they are stunning. Huge, but with glorious sound.

In a different category are my etymotic ER4S's. In-ear, sound blocking, great sounding. More expensive. Check out http://www.etymotic.com/ for more details. Oh yeah, and give serious consideration to the ety.com cell phone headset while you're there. Best one i've tryed, and i've tryed a bunch. A steal for $40.

In yet a different category, for beater/on the train listening, i use "Skullcandy Buds Inked" for less than $20 at Target.

An interesting coffee maker


I like coffee, good coffee that is. For ~$30 it's very hard to beat the Aeropress from Aerobie http://www.aerobie.com/Products/aeropress.htm Looks weird maybe, but makes great tasting coffee with little fuss or mess. Also good for camping...

Friday, November 7, 2008

I wanted to execute JavaScript in a Java program. Rhino looked like it would do the trick, but there is no DOM without a browser, and i wanted to run browser-less. I found a lot of discussion around this but none worked just right. Here is the incantation i used:
document = new Object ();
document.writeln = function (s)
{
if (s instanceof Array)
for (x in s)
document.writeln (s[x]);
else
java.lang.System.out.println (s);
}
document.write = function (s)
{
if (s instanceof Array)
for (x in s)
document.write (s[x]);
else
java.lang.System.out.print (s);
}

I imagine i could extend it to capture most of what a browser's DOM contains; maybe some day.
I also modified RunScript to read from System.in and inject the above code:
import java.io.FileReader;
import org.mozilla.javascript.*;

public class RunScript
{
public static void main(String args[]) throws
java.io.FileNotFoundException, java.io.IOException
{
String s = "document = new Object ();" +
"document.writeln = function (s)" +
"{ java.lang.System.out.println (s); };" +
"document.write = function (s)" +
"{ java.lang.System.out.print (s); };";

Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();

Object result = cx.evaluateString (scope, s, "<prelude>", 1, null);

FileReader in = new FileReader (args[0]);

result = cx.evaluateReader (scope, in, args[0], 1, null);

System.err.println(Context.toString(result));

}
finally
{
Context.exit();
}
}
}

More practice with forms and php

First, carefully read http://www.w3.org/TR/html401/interact/forms.html and ask any questions you have. Here is a very simple form:
<html>
<head>
<title>A very simple form</title>
</head>
<body>
<form action="display.php" method="post">
<input name="string">
<input type="submit">
</form>
</body>

And here is a very simple php page to display the results:
<html>
<head>
<title>Display the result of a form submission</title>
</head>
<body>
The contents of the form submission are:

<?php
print_r ($_REQUEST);
?>

</form>
</body>

Save these two files and get them working on your machine. Given this, we can create a page for a simple calculator:
<html>
<head>
<title>A Simple Calculator</title>
</head>
<body>

<form action="calculator.php" method="post">
<input name="number1">
<select name="operator">
<option selected value="plus">+</OPTION>
<option value="minus">-</OPTION>
<option value="divided by">/</OPTION>
<option value="times">*</OPTION>
</select>
<input name="number2">
<input type="submit">
</form>

</body>
And the corresponding code to make it work:
<html>
<head>
<title>Calculator Results</title>
</head>
<body>

<?php
$number1 = (int) $_REQUEST["number1"];
$number2 = (int) $_REQUEST["number2"];
$operator = $_REQUEST["operator"];

echo $number1 . " " . $operator . " " . $number2 . " equals ";

if ($operator == "plus")
echo $number1 + $number2;
else if ($operator == "minus")
echo $number1 - $number2;
else if ($operator == "times")
echo $number1 * $number2;
else if ($operator == "divided by")
echo $number1 / $number2;
?>

</form>
</body>
Save these two files and get them working on your machine. As PHP is embedded in HTML we can have just one form to both create the form and evaluate it. This time, we'll submit the page to itself:
<html>
<head>
<title>A Simple Calculator</title>
</head>
<body>

<form action="calculator2.php" method="post">
<input name="number1">
<select name="operator">
<option selected value="plus">+</OPTION>
<option value="minus">-</OPTION>
<option value="divided by">/</OPTION>
<option value="times">*</OPTION>
</select>
<input name="number2">
<input type="submit">
</form>

<?php
$number1 = (int) $_REQUEST["number1"];
$number2 = (int) $_REQUEST["number2"];
$operator = $_REQUEST["operator"];
if ($operator == "")
$operator = "plus";

echo $number1 . " " . $operator . " " . $number2 . " equals ";

if ($operator == "plus")
echo $number1 + $number2;
else if ($operator == "minus")
echo $number1 - $number2;
else if ($operator == "times")
echo $number1 * $number2;
else if ($operator == "divided by")
echo $number1 / $number2;
?>

</body>
</html>
Save this file and get it working on your machine. Now, go back and redo the JavaScript coffee assignment first as two pages, then as one.

Things to consider when creating web applications.
  1. What data are needed?
  2. What operations are done on the data?
  3. What logic is needed to make sure the operations work on all possible data and create the correct results?

Wednesday, November 5, 2008

Blackberry on Ubuntu

retrieved barry-0.14.tar.bz from http://sourceforge.net/projects/barry. needed to add the g++ and libusb-devel packages in order to configure and make.

Monday, October 27, 2008

Switching backgrounds in gnome

Surprisingly, gnome doesn't have a built in background switcher to change the background every N minutes. I found some on the 'net but didn't like any i found, so wrote my own as i'm want to do.

I have it start every time i log in by going to System -> Preferences -> Personal -> Sessions (Add):



#! /bin/bash

# System -> Preferences -> Personal -> Sessions

function dohelp() {
echo "$0 has three optional arguments."
echo "'-d dirname' to specify the directory to examine (~/Backgrounds"
echo " by default)."
echo "'-s sleep' to specify the number of seconds to sleep between"
echo " changing backgrounds (1800 (half an hour) by default)."
echo "'-m method' to specify the method of displaying the images."
echo " Values are:"
echo " 'zoom' to fill the screen and chop off any extra from the two"
echo " edges that overflow. Aspect ratio is maintained. This is"
echo " the default."
echo " 'scaled' to fit the image to two edges and fill with the"
echo " background color on the two edges that don't reach."
echo " Aspect ratio is maintained."
echo " 'streched' to fit the image to all four edges while not"
echo " maintaining the aspect ratio."
echo " 'centered' to place on the screen with no scaling at all"
echo " 'wallpaper' to repeat the image as many times as it will fit"
echo " with no scaling."
echo " One can also have picture-specific methods by creating a file"
echo " prefixed by a dot ".DSC0001.jpg for example" that has one word"
echo " in it, either zoom, scaled, streched, centered, or wallpaper."
echo " If none is specified, the default is used."
exit
}

DIRNAME=~/Backgrounds
SLEEP=1800
METHOD=zoom

while getopts 'd:s:m:h' OPTION
do
case $OPTION in
d) DIRNAME="$OPTARG" ;;
s) SLEEP="$OPTARG" ;;
s) METHOD="$OPTARG" ;;
h) dohelp ;;
?) echo "Usage: [-d directory] [-s sleep] [-m method]" >&2
exit 2
;;
esac
done

FILENAME=/desktop/gnome/background/picture_filename
OPTIONS=/desktop/gnome/background/picture_options

method=$METHOD
gconftool-2 --type string --set $OPTIONS $method

while true
do
# (re)read directory to pick up any new files
for i in $DIRNAME/*
do
filename=${i#$DIRNAME/}
# echo $filename

methodfile=$DIRNAME/.$filename
if [[ -e $methodfile ]]
then
# echo $methodfile exists
newmethod=`cat $methodfile`
else
newmethod=$METHOD
fi

if [[ $newmethod != $method ]]
then
gconftool-2 --type string --set $OPTIONS $newmethod
method=$newmethod
fi

gconftool-2 --type string --set $FILENAME $i

sleep $SLEEP

done
done

YAF with FC8

Yet another frustration with Fedora Core 8.

So, i want to sync with the local calendar server via evolution-jescs. Not in the yum repositories, naturally. Grabbed the latest source, 2.24. Needed to install intltool (easy) and libsoup 2.4 (impossible as it needs a newer version glib). 2.23, same deal. Etc. Had to go back to 2.12 to get it compiled. And that didn't work in the end either.

Ubuntu you ask? Installed via synaptics and worked the first time.

You connect the dots.

Image previews in nautilus

I wasn't getting previews for images on a compact flash drive attached via a USB connector in nautilus. Turns out, nautilus seems to believe that isn't a "local" drive, so under Preferences, Preview, Show Thumbnails, one has to drop down to "Always". Also see http://ubuntuforums.org/showthread.php?t=244898 for how to get around the error "The filename "..." indicates that this file is of type "jpg document". The contents of the file indicate that the file is of type "JPEG image""

Tuesday, October 21, 2008

Formatting arrays in Ruby

So i've been playing around some more with Ruby. The default formatting of arrays leaves something to be desired in my opinion. Here's what i use instead:

class Array
def to_s
'[' + collect{|x| x.to_s}.join(', ') + ']'
end
end

Saturday, October 18, 2008

Easy ginger tea

1.5 cup water, 1 teaspoon ground ginger. Microwave for 2 minutes. Add 1-2 teaspoon honey. Strain. Drink.

Sunday, October 5, 2008

Some PHP practice problems

Given:

<?php
echo "Please enter your name: ";
$name = trim (fgets (STDIN));
echo "Welcome, $name\n";

if ($name == "Sushil")
echo "You rock!!!\n";

print "I'm now going to count to 10\n";

for ($i=1; $i <=10; $i++)
echo $i . " ";

echo "\n";
?>


extend to the following:
  1. read three numbers and print the square of each,
  2. read three numbers, sort them, and print the square of each,
  3. print the even numbers from 0 to 20, and
  4. print the current date.
A useful resource is the php tutorial.

launch4l

I wanted to create a self-launching UNIX jar file, similar to what launch4j does for Windows. There are a couple of solutions out there, but none worked well for me. So I wrote my own. Here it is (formatted via http://formatmysourcecode.blogspot.com/):

#! /bin/bash

path=$1
jarname=${path##.*/}
basename=${jarname%%.jar}

## want substitutions this time as we need jarname expanded
cat - << ONE > $basename
#! /bin/bash

trap 'rm -f /tmp/$jarname' ERR
rm -f /tmp/$jarname
ONE

## but not here
cat - << "TWO" >> $basename
UUDECODE=`which uudecode 2> /dev/null`
if [ "$UUDECODE" = "" ]
then
UUDECODE=`which gmime-uudecode 2> /dev/null`
if [ "$UUDECODE" = "" ]
then
echo "No uudecode command found in $PATH, exiting"
exit 1
fi
fi

TWO

## but here again
echo '$UUDECODE -o /tmp/'$jarname' << "ENDOFJAR"' >> $basename

UUENCODE=`which uuencode 2> /dev/null`
if [ "$UUENCODE" = "" ]
then
UUENCODE=`which gmime-uuencode 2> /dev/null`
if [ "$UUENCODE" = "" ]
then
echo "No uuencode command found in $PATH, exiting"
exit 1
fi
fi

$UUENCODE $path /tmp/$jarname >> $basename

cat - << THREE >> $basename
ENDOFJAR

java -jar /tmp/$jarname \$*
rm -f /tmp/$jarname
THREE

chmod u+x $basename