Our new 2009 Honda Fit

Rachel got a new car! A 2009 Honda Fit Base Automatic – a distinct upgrade from the 1988 Toyota Corolla FX. The safety improvement is incredible, let along all the other modern features! The biggest problem was me forgetting my checkbook when we went to pick it up. The economy is definitely having issues though as we got this for a hundred bucks under invoice, which is fairly amazing for a Honda. Of course even the famed honda reliability has limits, my 95 accord had the front rotors warp fairly badly so I just had to get those replaced which was annoyingly expensive as they are press fit rotors which require extra effort. Anyway super happy with the fit, it’s fun to drive, exceptionally roomy (which is amazing given it is only an inch longer than the FX it replaces.) and generally awesome!

Posted in Uncategorized | Leave a comment

SantaCon 2008 The Klassic Kris Kringle route

We participated in the 2008 San Francisco SantaCon this year and had a blast. We started at pier 39 with several hundred other santas and roamed the city from there, providing SF tourists with some good stories and holiday cheer. Many photos were taken, view a selection of them here in the Santacon SF Gallery. Enjoy the video clip of santas dancing at 4pm in a north beach club, watch it now! Don’t forget about going to Santacon next year.

Posted in Uncategorized | Leave a comment

Heath Ceramics

We recently went to an open house
at Heath Ceramics. A high
end ceramics manufacturer in Sausalito and definitely an interesting
visit. As a hobbiest potter, I was a little torn as to what to think
about their setup. The ‘handcrafted’ portion of what they do is very
minimal compared to what a traditional defined potter does. They use
forms, slip-casting, and jiggers to make pretty much everything. The
human element seems most prevelent in cleaning up the pieces before
firing, and glazing them. I certainly understand why they do things
the way they do, it is a fine line to walk to be able to make enough
pieces to actually be a large business that can do global orders and
still have some of the desirable characteristics of traditional
pottery. Throwing by hand takes forever in comparision an automated
factory lacks character. For example they can form a large bowl in 30
seconds with their not quite totally mechanized process. Cleaning it
up, getting it glazed with a airbrush, and fired doesn’t take much
longer it terms of human time that goes in the bowl. The bowls will
be almost exactly the same but just slightly different enough from
each other that they have much more character than something that
really is produced in a modern automated factory somewhere that turns
up in a big box store for 30 bucks. My qualms with the
“marketing message” vs what I percieve as “the reality of the
situation” aside, they have a great facility. Huge kilns with drop
down walls made of spun glass are super efficent and I’m massively
envious of them, big dry rooms, awesome glazing stations, and a
wonderful clay mixing/recyling room. The tour was great because
during the openhouse they actually have people at the various stations
showing how all the tools work (typically the tours wouldn’t have any
demonstrations) and the workers are quite capable of knocking out
piece after piece – though we were on the last tour and I suspect the
workers all wanted to go home and get some use out of their
weekend. ;) Their tiles were really nice and I know from making tiles
myself what a pain it can be to do those right. The designs are all
nice, mostly post modern, that for the most part have been around for
40+ years. The founder was a potter and is exhibited in various
design museums, and I suspect her name and the assicated prestige of
Heath ceramics really helps them in the business and global
marketplace as being a status symbol since while they can knock out
maybe more pieces than a tradition potter they are still very limited
in production compared to a huge factory in China. I think that if
one were able to afford it the pieces are great and much better than
your big box store stuff. They do have seconds and overruns on tile
availble at a discount, and the openhouses each year they sell everying
at 20% off which is even better. If I ever end up with a house that
needs some tile I would definitely check them out.

Posted in Uncategorized | Leave a comment

Migrating Gallery Metadata

For a number of years back in the day I used the gallery.menalto.com software to host an online gallery of photos. Back in this rough and tumble wild
west days of metadata there weren’t great standards that could handle all possible metadata cases – and so the metadata was all stored in serialized php objects.

Fast forward to today, where there are great ways to store metadata for a photo right there with the photo. You can have exif, xmp, an iptc (to name some popular choices) and all the photo applications are aware enough to use that data. I only had limited meta data in the gallery software (title, caption, comments) but I had thousands of photos and the idea of entering that stuff in by hand was not appealing, neither was throwing it away. Thus I wrote some code to deal with it. It isn’t pretty and isn’t super fast but it does work.

The unserialize.php script is fairly straight forward, you feed it a photos.dat file and it spits out a line for each photo with filename, title, caption, comments and if the file was hidden or not.

unserialize.php:

#!/usr/bin/php

# Take the first argument as the photo.dat file we want to unserialize
$lines = file_get_contents($argv[1]);

# In order to access any of the unserialized class objects there needs
# to be a class definition for the objects, since I don't have the old
# gallery code we just make some empty definitions.
class albumitem {};
class image {};
class comment {};

$objects = unserialize($lines);

# To see what is availible in the object we can var dump it
#var_dump($objects);

# Go through all the photos
foreach ($objects as $obj) {

# Debugging for what is in the photo object
# var_dump($obj);

$img = $obj->image;
$title = $obj->phototitle; # extraFields->Title
$cap = $obj->caption;
$hidden = $obj->hidden;

# There can be multiple comments so build a little xml of all the
# comment content that can be output as a single string.
$comments = $obj->comments;
$commentXML = “”;
if ( $comments != null) {
# var_dump($comments); #debug
$commentXML = ““;
foreach ($comments as $comment) {
$text = $comment->commentText;
$text = preg_replace(“[\n\r]“,”
“, $text);
$name = $comment->name;
$datePosted = $comment->datePosted;

$commentXML .= “$name” . date(“Y-m-d H:i:s”, $datePosted) . “$text }
$commentXML .= "“;
}

# Back before gallery had both title and caption I hacked in title, then when
# gallery added ‘extraFields’ I migrated the titles into an extraField called title
# so I go and check if that title exists in extra fields then pick which title I
# should be using
$extraFields = $obj->extraFields;
#var_dump($extraFields);
$extraTitle = $extraFields['Title'];
#var_dump($extraTitle);
$theTitle = $extraTitle;
if ($title != null) {
$theTitle = $title;
if (strlen($extraTitle) > 0 and strlen($title) > 0 and $extraTitle != $title) {
echo “Mismatched titles: $extraTitle $title”;
}
}

# build the file name from the name and image type
$file = “”;
if ($img->name != null and strlen($img->name) > 0) {
$file = “$img->name.$img->type”;
}
$cap = ereg_replace(“[\n\r|\r\n|\r|\n]“, ” “, $cap);
$commentXML = ereg_replace(“[\n|\r|\r\n|\n\r]“, ” “, $commentXML);

# print out all the data separated by double bars || for easy parsing
echo “$file||$theTitle||$cap||$commentXML||$hidden\n”;
#var_dump($img);
}

?>

The next step is to run this on all the photos.dat files I have, and take that meta data and insert it into the actual files.
For this I wrote a little perl script. The perl script works on some assumptions, mostly on file and directory names.
1) It assumes: The photos.dat files are in a directory named with the date in YYYY_MM_DD format (for example 2003_07_04 4thofJuly)
2) It assumes: That the actual image files are also in a directory that contains the YYYY MM and DD (in any order).
3) It assumes: That the file names of the actual images match the names in the photos.dat serialized object.

To acomplish I had to write some scripts, first many of my albums were named DD_MM_YYYY name, which wasn’t super helpful so I wrote a script get them all in the same date format, and munges the file names in the same way gallery does. (You will probaly have to fiddle with the script to make it work for your own situation.) This takes care of assumption 1 and 3.

!/usr/bin/perl -w

use strict;

my $path = “/Users/eric/Pictures/2002″;
opendir(DIR, “$path”) || die “can’t opendir . $!”;
# get dirs in DD_MM_YYYY format
my @dirs_to_rename = grep { /^\d\d_\d\d_\d\d\d\d.*/i && -d “$path/$_” } readdir(DIR);
closedir DIR;

foreach my $dir (@dirs_to_rename) {
if ($dir =~ /(\d\d)_(\d\d)_(\d\d\d\d)(.*)/) {

opendir(FDIR, “$path/$dir”) || die “can’t opendir . $!”;
my @files_to_rename = grep { /.*-.*/i && -f “$path/$dir/$_” } readdir(FDIR);
closedir FDIR;
foreach my $file (@files_to_rename) {
# make sure the named is munged as gallery expects
my $newFile = $file;
$newFile =~ s/-/_/g;
$newFile =~ s/JPG$/jpg/g;
$newFile =~ s/_\.jpg/\.jpg/g;
my $cmd = “mv $path/$dir/$file $path/$dir/$newFile”;
print “\t$cmd\n”;
`$cmd`;
}

my $cmd = “mv $path/$dir $path/$3_$1_$2$4″;
print $cmd,”\n”;
`$cmd`;
}
}

Assumption 2 seemed like a given for me since I have always included year month date in my folder names, and ignoring order it seems like I would be fine,
however I found a few cases where I had put the wrong date in the gallery album and correct date in the folder on my computer. So I had to write a little
script to check that all the folders with photos.dat files actually had matching folders of images with the same date. Thus I wrote another script, this one assumes that you have run updatedb recently so the locate command will work. Basically I parse out the date of a photos.dat file path, then grab the first
image and locate the image which gives me all the paths, I then parse those paths looking for one that matches the data and the folder location of my images sans metadata.

#!/usr/bin/perl -w

use strict;

my @photoDats = split(/\n/,`find . -name “*photos.dat”`);

foreach my $photoDat (@photoDats) {
my @unserializedDataLines = split(/\n/, `./unserialize.php $photoDat`);

my $year = “”;
my $month = “”;
my $day = “”;
if ($photoDat =~ /(\d\d\d\d)_(\d\d)_(\d\d)/) {
$year = $1;
$month = $2;
$day = $3;
} else {
print “No date associated with photos.dat ($photoDat)\n”;
}

my $found = 0;

foreach my $photoDataLine (@unserializedDataLines) {
if (length($photoDataLine) == 0) {
next;
}

my ($file, $title, $caption, $comment, $hidden) = split(/\|\|/, $photoDataLine);
if (length($file) == 0) { next; }

my $cmd = “locate $file”;
my $result = `$cmd`;
my @files = split(/\n/, $result);
if ($#files + 1 == 0) {
print “Could not file $file\n”;
}

# my photos .dat files are in ../eric/albums/ and the folder of images with no
# meta data are in ../eric/Pictures/YYYY/etc Aperture managed to pick up some
# of the album folders from long in the distant past though an iphoto import and
# iphoto had sucked them down while scanning the drive, oye! So do these
# various checks on the path to make sure the path really is a path with
# the correct date in correct location
foreach my $fileLoc (@files) {
if ($fileLoc !~ /Users\/eric\/Pictures/) {next;}
if ($fileLoc =~ /Aperture/) {next;}
if ($fileLoc !~ /$year/) {next; }
if ($fileLoc !~ /$month/) {next; }
if ($fileLoc !~ /$day/) { next; }
$found = 1;
last;
}

if ($found == 1) {
last;
}
}

if ($found == 0) {
print “No matches: $photoDat\n”;
}
}

This finds both photo.dat files that have a directory name that is a little off from the image file directory and it also finds instances where I had only loaded the images into gallery and hadn’t managed to keep a copy in my Pictures folder. For the later case I just make the approriate directory and copied the image files from gallery.

Finally I have the script that reads all the photos.dat files, unserializes them, finds all instances of those files, and updates the metadata.

process.pl:

#!/usr/bin/perl -w

use strict;

my @photoDats = split(/\n/,`find . -name “*photos.dat”`);

foreach my $photoDat (@photoDats) {
my @unserializedDataLines = split(/\n/, `./unserialize.php $photoDat`);

my $year = “”;
my $month = “”;
my $day = “”;
if ($photoDat =~ /(\d\d\d\d)_(\d\d)_(\d\d)/) {
$year = $1;
$month = $2;
$day = $3;
} else {
print “No date associated with photos.dat ($photoDat)\n”;
}

foreach my $photoDataLine (@unserializedDataLines) {
if (length($photoDataLine) == 0) {
next;
}

my ($file, $title, $caption, $comment, $hidden) = split(/\|\|/, $photoDataLine);
if (length($file) == 0) { next; }

print “$file ====> $title ====> $caption ====> $comment\n”;
my $cmd = “locate $file”;
my $result = `$cmd`;
my @files = split(/\n/, $result);
print “FILES: ” , join(“-”, @files), “\n”;
if ($#files + 1 == 0) {
print “Could not file $file\n”;
}

# If the photo is hidden set rating to zero, otherwise set it to 1 as a place to
# start with rating them in lightroom
my $rating = 1;
if (length($hidden) > 0 and $hidden == 1) {
$rating = 0;
}

foreach my $fileLoc (@files) {
if ($fileLoc !~ /$year/) {print “Skipping $fileLoc does not contain $year\n”; next; }
if ($fileLoc !~ /$month/) {print “Skipping $fileLoc does not contain $month\n”; next; }
if ($fileLoc !~ /$day/) {print “Skipping $fileLoc does not contain $day\n”; next; }

if (length($title) > 0) {
$cmd = “exiv2 -M\”set Xmp.dc.title lang=x-default $title\” \”$fileLoc\”";
print $cmd, “\n”, `$cmd`;
}
if (length($rating) > 0) {
$cmd = “exiv2 -M\”set Xmp.xmp.Rating $rating\” \”$fileLoc\”";
print $cmd, “\n”, `$cmd`;
}
if (length($caption) > 0 or length($comment) > 0 ) {
$cmd = “exiv2 -M\”set Xmp.dc.description lang=x-default $caption $comment\” \”$fileLoc\”";
print $cmd, “\n”, `$cmd`;
}
}
# exiv2 -M”set Iptc.Application2.Credit String Mr. Smith” image.jpg
# set Xmp.dc.title lang=x-default Sunset on the beach
# set Xmp.xmp.Rating 1
# set Xmp.dc.description lan=x-default Descrition
# XmpText | XmpAlt | XmpBag | XmpSeq | LangAlt
# Xmp.dc.title LangAlt 1 lang=”x-default” Title
# Xmp.dc.description LangAlt 1 lang=”x-default” Caption
}
}

So there ya go. Hopefull that is useful to someone else at somepoint down the line.
I suppose one final point is if you had made descriptions for you albums you would need to write something like unserialize.php but that takes the album.dat file instead and strips out the description. The challenge there is where do you put that description? I’m thinking of just putting it in text file in the fold it is associated with, but that is a task for another time.

Posted in Uncategorized | Leave a comment

The honeymoon has arrived

Four plane rides and we have managed to get to Chan Chich Eco Lodge. The little plane was quite fun. :) The lodge is very luxurious and jungley, it has been raining quite a lot and all the rivers are super high but it was very nice the day we came in and it isn’t currently raining – we slept 13 hours last night so that is a win. I am currently fighting off a bit of a cold but hopefully will make it, this place is so relaxing it’s hard to imagine getting sick. We are having a great time so far!

Posted in Uncategorized | Leave a comment

Wedding Photos

Wedding Photos are available and have been for a while I’ve just been lazy about posting. You can see then in the gallery here on the blog. You can also see and order them from shutterfly.com The password to view them is 20080816 and you will need to make an account to be able to order.

Posted in Uncategorized | Leave a comment

Palin Voodoo Doll

Just in time for the debates, have yourself a chuckle at palinvoodoo.com’s Sarah Palin Voodoo doll.
Speaking of politics, I really need to stop watching the news because the GOP’s general horribleness frightens and angers me to no end.

Posted in Uncategorized | Leave a comment

Whirled Corpse Craft

Whirled is just what it sounds like,
an online “world” har har – oh my side! Written in Flash, and thus
very accessible from all the major browsers and computer platforms.
Part casual gaming, part social networking, part creators pallet -
it is really quit unique and has an array of wildly different things
to do. I personally was highly entertained by a little game called
“Corpse Craft” whose game play is described as: “Build an army of
re-animated corpses to destroy your foes in this puzzle-action
hybrid.” Which is quite apt. The art is great, the story and
game play entertaining. You play a game of ‘implode’ or ‘collapse’
or whatever else you want to call it on the bottom of the screen.
As you destroy groups of similarly colored blocks you increase the
number of resource blocks of the same color. You spend those
resources to launch different types of re-animated corpses across the
screen. The different corpses have different abilities that you are
trying to use to destroy your opponents corpse re-animation factory
on the other side of the screen, who of course is sending re-animated
corpses to try and destroy you. It starts off quit easy and gets
much harder for the last few levels. Regardless quite fun and
doesn’t take ages to get through.

Posted in Uncategorized | Leave a comment

Rachel and Eric get Married Huzzah

Rachel Diaz-Bastin and Eric Lundberg got married at 5pm at Cafe de La Paz in Berkeley in front of friends and family. It was a great time and we’ll have pictures up soon. Thanks to everyone who could make it, we are super happy! -eric and rachel

Posted in Uncategorized | Leave a comment

Marin Century Ride – 2008 106 miles on a bike – are you crazy?

So I did the Marin Century ride today, which was quite an event. The
longest ride I had done before was 45 miles up to the top of Mount
Tam, so this was a change! Mostly it is just a long time to be
riding a bike. There are several large hills on the route as you
can see on
the map
and there was a bit of a cross wind and head wind from time to time.
But, overall the weather was quite good. Sunny with a cool breeze
most of the day as we were near the coast. The early morning views
of valleys with clinging pieces of fog were classically Californian
coast. There were 4 rest stops on the route, all with lots of good
food and drink and restrooms. I had lunch part 1 at the second rest
stop and lunch part 2 at the third rest stop. After about 60 miles
my ass was starting to hurt – not surprisingly it continued to hurt
more for the rest of the ride. My left calf threatened cramp up but
never did. My right knee got a bit twingy after 80 miles and around
95 started to hurt if I put much force on it, so I mostly used my
left leg to get me up the last big hill then coasted the rest of the
way in. I thought it was interesting that I wasn’t really slowed
down by my cardio or my length strength but more due to the rest of
me wearing out. That is to be expected I think since I didn’t build
up slowly to a 100 miles. The book The Complete Book
of Long-Distance Cycling was pretty handy tool for figuring out
what I needed to do to train, but I only had 6 weeks and there is
only so much one can do. Oh and my right big toe had the outside
edge go numb, but it’s done that ever since that fateful backpacking
trip in ’98 so I was expecting it. I wore a lot of sunscreen but
got a little bit burned on the back of my calves as the sun shifted
around. I also had some king of bug fly into my shirt and get
caught which involved me then pulling over and frantically trying to
let said bug out as I could hear it buzzing around under my jersey.
Eventually I got it to fly out of my sleeve! The total route was
106 miles with 6250′ of elevation. From start to finish was about 9
hours for me. I was on my bike for 7 hours and 15 minutes, so
lunch, rest stops, and bug removal definitely took up some time. My
average speed was 14.3 MPH while I was on my bike. Definitely nice
that they had a good spread of food when I finished (including free
hagen-daz ice cream!) I certainly slept well that night. :)

Posted in Uncategorized | Leave a comment