November 30, 2005

36 empty carrier bags


36 empty carrier bags
Originally uploaded by savs.

A simple shop online with Tescos invariably results in a mountain of carrier bags. Almost every item lovingly individually wrapped. 100% biodegradable, the bags scream at me in big blue print. 100% full landfill sites I shout back, frustrated that my no car needed ecologically sound online shopping has turned into an environmental disaster.



Not that I'm really overly bothered about the whole environment thing. It did take twice as long to unpack the food though, which is a bit irritating. Why not deliver in recycled cardboard boxes, which can be unloaded from the van directly into the kitchen?


Posted by flickr at 12:36 PM

November 29, 2005

links for 2005-11-29

Posted by delicious at 10:17 PM

November 28, 2005

Digital Rights in the UK

Tomorrow, London: Digital Rights in the UK: Your Rights, Your Issues. And while you're at it, help support an organisation that will campaign for digital rights in the UK.

This is important, folks. It's your digital tomorrow we're talking about here.

Posted by savs at 10:31 PM

links for 2005-11-28

Posted by delicious at 10:17 PM

Back to the Future

And so the critical backlash against Ruby on Rails has truly gotten underway. Elliotte Rusty Harold: "a very common mistake made by developers who are mired in 1980s style of applications and have never understood the Web, and probably never will." Steven Noels: "the advent of using a platform which requires you to worry about shooting blanks isn't very appealing to me." Berin Loritsch: "integration with Apache2 is shaky at best and I get unexplained errors between development and production environments."

I'm sure this is just the beginning, as more and more people make the switch to Rails, only to find that what they gain in quick initial results they lose due to the framework's immaturity. Which brings me to what I've been thinking almost ever since David first introduced me to Rails last year: the true value of Rails is not necessarily the framework itself.

The true value is in what Rails has taught us about who we are and how we do our jobs. Write less code. Convention over configuration. Don't repeat yourself. These are all common-sense statements, and the lesson is that someone needed to remind us of them, and challenge our assumptions about how we approach the problem of web applications.

For those of us that have been in this game for a while, and have progressed steadily from CGIs written in C to scripts written in Perl, to PHP and ASP then JSP and J2EE, it feels like we've made steady progress and improved on what went before. But starting with a fresh canvas, as the Rails community have done, teaches us a lot about the baggage we've carried with us in our quest to improve on the frameworks we used before. XML sit-ups seemed like a small price to pay for dispensing with the legacy of CGIs and scripting languages. But Rails shows us that we should be braver, and define our best practices, so we can let the computer do more work for us.

Posted by savs at 8:06 PM | Comments (1)

November 27, 2005

Simple CRUD in Cocoon

I've finally had a chance to try out the super-easy SQL/Form integration that Sylvain announced last month on the cocoon-dev mailing list. It really is pretty straightforward, and it somehow feels more 'right' to throw objects around in flowscript rather than using SQL Transformer.

It's still not as quick to get up and running as Rails, but it's not bad: in just a few hours this afternoon, I've got the basics of a CRUD application working. It's much less scary than having to get Hibernate or OJB working, and less hassle than writing all the relevant beans. There's some places I'd like some magic to happen with dynamically-generated flowscript and jx from database metadata, but I guess that can follow in time.

Right, back to the app ...

Posted by savs at 5:32 PM

Maven and Cocoon

(This is a draft of a document I hope to add to the Cocoon docs. Yes, it's only Maven 1.x at the moment. Yes, it's only unix-based at the moment. Feedback welcome...)

Luminas have been using Maven and Cocoon on various projects recently. There's relatively poor documentation "out there" on how to do so - a reference to Maven on the Cocoon wiki, some details on building and deploying Cocoon with Maven.

Why would you want to use Maven, and the Maven Cocoon plugin? Maven is a great tool for helping you develop projects, and can ease the task of managing and downloading dependencies, building, and generating project documentation. It can also do much more, take a look at the list of Maven 1 plugins to get an idea of the possibilities.

The maven cocoon plugin helps by managing the build properties and blocks properties files in Cocoon for you, and makes the Cocoon build a part of your overall project build. It can also help you by preparing a deployable version of Cocoon.

The maven-cocoon-plugin was developed by Otego.

I assume you've installed Maven (version 1 currently for this) and Cocoon (2.1.7 or later), and got both working. The first thing you need to do is create a place to work and generate the appropriate directory hierarchy for your application. Assuming a fictional project name of 'macaroon', this is what you do:

mkdir macaroon
cd macaroon

Now we create the skeleton directories, using the Maven application generator plugin:

maven genapp

(If you have not yet used the genapp plugin, maven will automatically download the relevant dependencies, e.g. commons-jelly-tags-interaction.)

Enter a project template to use: [default]
(hit return)
Please specify an id for your application: [app]
macaroon
Please specify a name for your application: [Example Application]
Macaroon
Please specify the package for your application: [example.app
uk.co.luminas.macaroon
build:start:

genapp:
[copy] Copying 1 file to ~/macaroon/src/java/uk/co/luminas/macaroon
[copy] Copying 3 files to ~/macaroon/src/test/uk/co/luminas/macaroon
[copy] Copying 1 file to ~/macaroon
[copy] Copying 2 files to ~/macaroon
BUILD SUCCESSFUL
Total time: 27 seconds

Great! We have a set of empty directories to work on. Next, we need to fill out the project descriptor project.xml, or at least update the template with content of our own. A sample project descriptor might be:

<?xml version="1.0" encoding="UTF-8"?>
<project>
<pomVersion>3</pomVersion>
<id>macaroon</id>
<name>Macaroon</name>
<currentVersion>1.0</currentVersion>
<organization>
<name>Luminas Limited</name>
<url>http://www.luminas.co.uk/</url>
<logo>http://www.luminas.co.uk/images/luminas_187x100.png</logo>
</organization>
<inceptionYear>2005</inceptionYear>
<package>uk.co.luminas.macaroon</package>
<description>A demonstration project showing how to use maven and cocoon together.</description>
<shortDescription>How to use maven with cocoon.</shortDescription>
<dependencies/>
<build>
<sourceDirectory>src/java</sourceDirectory>
<unitTestSourceDirectory>src/test</unitTestSourceDirectory>
<unitTest>
<includes>
<include>**/*Test.java</include>
</includes>
</unitTest>
<resources>
<resource>
<directory>src/conf</directory>
<includes>
<include>*.properties</include>
</includes>
</resource>
</resources>
</build>
</project>

Next we need to create our maven build file, maven.xml, with instructions on how to build the project. A sample maven build file might be:

<project default="usage"
xmlns:ant="jelly:ant"
xmlns:maven="jelly:maven"
xmlns:j="jelly:core"
>

<goal name="usage" description="Prints usage information">
<ant:echo></ant:echo>
<ant:echo>===============================================================================</ant:echo>
<ant:echo></ant:echo>
<ant:echo>Maven Goals:</ant:echo>
<ant:echo> install : build and install all required components and settings into Cocoon</ant:echo>
<ant:echo> uninstall : uninstall all components, resetting Cocoon as it was</ant:echo>
<ant:echo> build-cocoon : builds Cocoon specifically for this project</ant:echo>
<ant:echo> clean : clean the repository from generated artifacts</ant:echo>
<ant:echo></ant:echo>
<ant:echo>===============================================================================</ant:echo>
<ant:echo>NB. All targets require that you have set the environment variable $COCOON_HOME</ant:echo>
<ant:echo>COCOON_HOME: ${env.COCOON_HOME}</ant:echo>
<ant:echo>===============================================================================</ant:echo>
</goal>

<!-- Get property values from the environment and reset any properties -->
<preGoal name="build:start">
<ant:property environment="env"/>
<ant:property file="${basedir}/local.build.properties"/>
</preGoal>

<!-- install dependencies and mount the webapp into the target Cocoon -->
<goal name="install" prereqs="clean,build-cocoon">
<attainGoal name="cocoon:install-deps"/>
<attainGoal name="cocoon:mount"/>
</goal>

<!-- uninstall dependencies and mount the webapp into the target Cocoon -->
<goal name="uninstall">
<attainGoal name="cocoon:uninstall-deps"/>
<attainGoal name="cocoon:unmount"/>
</goal>

<!-- Executes the 'clean:clean' goal on all sub projects -->
<goal name="clean">
<attainGoal name="clean:clean"/>
<ant:delete dir="${basedir}/target"/>
</goal>

<!-- Convenience goal for less typing -->
<goal name="build-cocoon">
<attainGoal name="cocoon:build-cocoon"/>
</goal>

<!-- ==================== -->
<!-- Cocoon-related tasks -->
<!-- ==================== -->
<!-- Collects resources needed for proper self containment of the application -->
<postGoal name="cocoon:install-deps">
<j:set var="targetInstallationDir" value="${env.COCOON_HOME}/build/webapp"/>
<attainGoal name="copy-additional-resources"/>
</postGoal>

<!-- Collects resources needed for proper self containment of the application -->
<postGoal name="cocoon:build-package-dir">
<j:set var="targetInstallationDir" value="${maven.build.dir}/cocoon/${pom.artifactId}/WEB-INF/classes"/>
<attainGoal name="copy-additional-resources"/>
</postGoal>

<!-- Collects resources needed for proper self containment of the application -->
<goal name="copy-additional-resources">
</goal>

</project>

Now, typing maven will give you instructions on the maven goals available.

build:start:

usage:
[echo]
[echo] ===============================================================================
[echo]
[echo] Maven Goals:
[echo] install : build and install all required components and settings into Cocoon
[echo] uninstall : uninstall all components, resetting Cocoon as it was
[echo] build-cocoon : builds Cocoon specifically for this project
[echo] clean : clean the repository from generated artifacts
[echo]
[echo] ===============================================================================
[echo] NB. All targets require that you have set the environment variable $COCOON_HOME
[echo] COCOON_HOME: /Users/savs/Development/cocoon-2.1.8
[echo] ===============================================================================
BUILD SUCCESSFUL
Total time: 4 seconds
Finished at: Sat Nov 26 17:44:22 GMT 2005

The next task is to add suitable entries to project.properties to control for example what blocks will be required by your application, and where to retrieve dependencies from. This is done as follows:

maven.repo.remote = http://project.otego.com/maven,http://www.ibiblio.org/maven
maven.cocoon.blocks.list = ajax,databases,forms,serializers,xsp

Now that the repo is added, download the cocoon plugin:

maven plugin:download -DgroupId=maven -DartifactId=maven-cocoon-plugin -Dversion=1.0.10

Let's try building Cocoon:

maven build-cocoon

You should see that just our selected blocks are built into Cocoon:

(...)
[exec] cocoon-block-ajax-compile:
(...)
[exec] cocoon-block-forms-compile:
(...)
[exec] cocoon-block-serializers-compile:
(...)
BUILD SUCCESSFUL
Total time: 1 minutes 5 seconds

If you need to build your project against Cocoon, add the Cocoon dependency to the project.xml file:

<dependencies>
<dependency>
<groupId>cocoon</groupId>
<artifactId>cocoon</artifactId>
<version>2.1.7</version>
<type>jar</type>
</dependency>
</dependencies>

Now when you type maven build-cocoon you will see that Maven downloads Cocoon:

Attempting to download cocoon-2.1.7.jar.
1265K downloaded

Where to put your cocoon app files? I suggest the following layout:

mkdir -p src/cocoon/app/content
mkdir src/cocoon/app/flow
mkdir src/cocoon/app/forms
mkdir src/cocoon/app/messages
mkdir -p src/cocoon/app/resources/images
mkdir src/cocoon/app/resources/css
mkdir src/cocoon/app/stylesheets
touch src/cocoon/app/sitemap.xmap

A common patch to make to Cocoon might be to add a datasource (of course in real life you'd need a patch to add the driver to web.xml too).

Create directory structure for patches:
mkdir -p src/cocoon/install-patches
mkdir -p src/cocoon/uninstall-patches

Create the patch file 'datasources.xconf' in install-patches:

<?xml version="1.0"?>
<xconf xpath="/cocoon/datasources" unless="jdbc[@name='macaroon']">
<jdbc name="macaroon">
<pool-controller min="5" max="10"/>
<dburl>jdbc:postgresql://localhost/macaroon</dburl>
<user></user>
<password></password>
</jdbc>
</xconf>

... and create the unpatch file 'datasources.xconf' in uninstall-patches:
<?xml version="1.0"?>
<xconf xpath="/"
remove="/cocoon/datasources/jdbc[@name='macaroon']"></xconf>

Next time you build your application, you should see the above being patched into Cocoon:

[cocoon-xpatch] Processing: macaroon/src/cocoon/install-patches/datasources.xconf
[cocoon-xpatch] Writing: cocoon-2.1.8/build/webapp/WEB-INF/cocoon.xconf

But wait - you need the Postgres JDBC driver in order for it to work. Not a problem, simply add it to the project.xml as an additional dependency. To make sure it gets copied into Cocoon's lib directory, use cocoon.deploy:

<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.0-312.jdbc3</version>
<type>jar</type>
<properties>
<cocoon.deploy>true</cocoon.deploy>
</properties>
</dependency>

Coming up: building a distributable war file.

Posted by savs at 4:59 PM | Comments (1)

November 26, 2005

Updates on iTunes and Migration

In response to my iTunes complaints, Paul told me:

uh, you can ask apple to de-authorise computers for you.

He goes on to quote Apple (iTunes: About Music Store authorization and deauthorization):

If you find you have reached 5 authorizations due to system upgrades, you can reset your authorization count by clicking Deauthorize All in the Account Information screen. Note: You may only use this feature once per year. The Deauthorize All button will not appear if you have less than 5 authorized computers or if you have used this option within the last 12 months.

Ok, that's good. I still think it's annoying hoops to jump through, but it might buy me more time until JHymn works again.

Meanwhile, talking to David earlier (he of the ever-moving ever-broken blog), about migration, I thought I should mention the migration assistant built in to Tiger. I didn't use it myself (I wanted a duplicate, not a fresh install with copied bits). Anyway:

15:37:41 me: http://www.andrewsavory.com/blog/archives/000971.html
15:40:41 david: wow
15:40:44 david: as easy as that?
15:40:47 me: yup
15:40:50 david: so but er
15:40:50 me: even easier for you
15:40:55 david: really?
15:41:05 me: 1 mo, finding link
15:41:18 me: http://www.apple.com/macosx/features/setup/
15:42:51 david: yikes
15:43:15 david: bloody hell
15:43:18 david: that's very very cool!
15:43:20 me: yep
15:43:37 david: ok lovelyness
15:43:42 david: smart
15:43:43 david: nice
15:43:45 david: *furry*
15:43:47 me: mac++ ;-)
15:43:50 david: heh
15:43:52 david: we're an advert!
15:43:53 david: :-)
15:43:57 me: indeed

Excuse any formatting-fu, I'm copying/pasting from Adium and ecto has decided to preserve fonts, backgrounds etc.

Posted by savs at 5:02 PM

Machine migration

two powerbooksPossibly the easiest migration ever?

Moving from one Powerbook to another identical Powerbook was as simple as ABC:

  • join the machines with a firewire cable
  • boot the destination machine in firewire target mode (hold down T on boot)
  • tell carbon copy cloner on the source machine to copy everything onto the target firewire drive

Ok, it took the best part of four hours to copy the drives (about 70gb of data). But when it was done, I was able to boot the destination machine and carry on right where I left off, as though nothing had happened.

(That's a slight exaggeration: two things needed fixing. First, for some reason, the built-in OS X battery indicator had returned on the destination machine. I use SlimBatteryMonitor, so I had to uncheck 'Show battery status in the menu bar' in the Energy Saver system preferences. Secondly, SMARTReporter noticed that the hard disk was actually a slightly different make, and asked me to confirm my preferences. And then there was the usual iTunes FoulPlay nonsense.)

Posted by savs at 2:39 PM

Trust is a two-way street

Back in March of 2004, I decided to trust iLife with some of my precious digital content: in particular, my photos and my music. For the most part, I have been happy since then, but the occasional problems have caused me to wonder if it was a great idea. There are bugs in iPhoto 4 which make it at times unusable (for example, it's difficult to sort in a sensible order, some text fields that habitually lose focus as you are typing in them). iTunes is fragile (if you move your tracks to an external drive, you will probably lose your play count) and the need to defend the music industry's interests means you can't do obvious things like keep your music on the iPod and play it from the iTunes interface (essential if you're on the road without aforementioned external drive).

I think I'm getting to the point where I am so put off by the Dubious Restriction Machinations of iTunes in particular that I need to seek out more open (and ideally libre) alternatives. Yesterday I did a wholesale move of my Powerbook across to an identical machine (more on that next). I could have swapped the hard disk into the other powerbook, but instead did the digital equivalent. On starting iTunes, I got the familiar warning that my computer was not authorised. After authorising, I'm told I'm just about out of lives:

Itunes Authorised

All because I forgot to play by Apple's rules and deauthorise my other computers. And this is only the second machine my music has been on. The other 'fair uses' were lost due to operating system upgrades or reinstallations. Sing along with me: ours is less and less a free society.

So right now I figure I have two choices. Convert all my music to MP3 (less than ideal; it's a lossy conversion) or re-import all my CDs as MP3s. Not a particularly tempting prospect. Unfortunately JHymn is not yet able to work around the restrictions in iTunes 6 (and arguably, why should users have to resort to quasi-criminal software to get fair use of their music?) As for the tracks I bought from the iTunes Music Store: I guess I should write that off as a bad idea, and start listening to libre music instead. Next time I feel the need to buy an album from iTunes, I'll give the money to the EFF instead.

The encroaching restrictions of iTunes make me fear for the rest of my digital data.

Funny, I remember being told years ago that FairPlay AAC was evil. Next time someone tells you that Free is good, don't necessarily write them off as a zealot or a crank. Maybe, just maybe, they are forward-thinking true prophets of our digital doom.

Posted by savs at 2:19 PM | Comments (1)

November 22, 2005

Die, MySQL, die!

You know what's coming by now, if you've read such balanced posts as MySQL sucks, MySQL makes me sick, or MySQL is a PITA.

Consider this fairly normal scenario: a database on one server that I need to move to another server. I might do it like this:

server1$ mysqldump my_database > db.sql
server2$ mysql my_database < db.sql

Unfortunately, if my_database happens to contain tables with foreign key constraints, we get the following delightfully informative error:
ERROR 1005 (HY000) at line 12: Can't create table './my_database/foo.frm' (errno: 150)

It turns out the way to resolve this is to use SET FOREIGN_KEY_CHECKS = 0; before you do the import, and SET FOREIGN_KEY_CHECKS = 1; after the import successfully completes.

So, my questions to the MySQL apologists are these:

  • Why do we get to see ERROR 1005 (HY000) instead of something intelligent?
  • Why doesn't mysqldump warn the user that it cannot safely create a dump that can be restored error-free?
  • Why doesn't mysqldump offer to prepend and append suitable FOREIGN_KEY_CHECKS lines to the output?
  • Why do people still use and even recommend this joke of a database, thereby forcing me to deal with it?
Posted by savs at 2:02 PM | Comments (7)

November 21, 2005

links for 2005-11-21

Posted by delicious at 10:17 PM

November 19, 2005

November 18, 2005

Cocoon 2.1.8 released

Cocoon 2.1.8 is out. Carsten emailed a list of the major changes, and the full changes are available as always.
Posted by savs at 11:35 AM

November 17, 2005

Top 20 geek novels

Following on from the Time top 100 novels comes the Guardian's top 20 geek novels. I do a little better here - I've read fourteen of them, and I have one of them on my bookshelf waiting (Microserfs). Here's the ones I've read:

  • H2G2
  • Nineteen Eighty-Four
  • Brave New World
  • Do Androids Dream of Electric Sheep?
  • Neuromancer (and almost all William Gibson)
  • I, Robot
  • Foundation (and actually almost all Asimov)
  • The Colour of Magic
  • Snow Crash (and almost all Neal Stephenson)
  • Cryptonomicon
  • Consider Phlebas (and almost all Iain [M] Banks)
  • Stranger in a Strange Land (and almost all Robert Heinlein)
  • The Diamond Age
  • Trouble with Lichen
Posted by savs at 9:02 AM | Comments (1)

November 16, 2005

links for 2005-11-16

Posted by delicious at 10:17 PM

This week's addiction

Last.fm radio
Posted by savs at 11:00 AM

November 13, 2005

links for 2005-11-13

Posted by delicious at 10:17 PM

Google

Google Open House London
I got the opportunity to visit Google last week, when their new office in London held an open house party. The event was an interesting insight into the mind of the company, and was certainly food for thought.

The evening took the shape of an introduction to Google in general, followed up by a more detailed explanation of what Google plans to do from here. London is to become the centre of development for their mobile applications, predominantly because of the more significant mobile adoption in Europe vs. the US, and also because it's a great city to live in with a good research base.

The introduction to Google at large was the best bit of the evening in my opinion. I've had a fairly good idea of what Google do and how they do it, but hearing it from them really drove home some of the messages (such as commodity hardware instead of high-end servers to power their datacentres). Some new stuff that I didn't know about, too: I hadn't realised just quite how huge their revenues from advertising were, or how overwhelming their market share is in just about every market in the world.

The most amazing thing of all was the description of what they are doing with machine translation: approaching it from a statistical methodology rather than an algorithm-centric approach. Their saying here - a ton of data is worth an ounce of algorithm - summed it up nicely and really shows how we have to think about things differently in a world where getting hold of that data is often much easier than coming up with ways of intelligently processing it. Google expect to be as good as (if not better than) human translators within the next few years. Wow.

Back to the mobile thing. Let me say this up front: I was quite disappointed with the vision that Google enunciated for this. As far as I could tell, it boiled down to "everything we already do, but on a phone". Now to be fair, moving all those services on to a mobile platform is not going to be easy. But I didn't really get any sense of forward-thinking or new ideas, just a rehash to gain more market share.

Things like ambient or location-based initiatives were played down (maybe these are difficult things to tackle without being evil?). And there didn't seem to be any new or unique ideas there. Sure, leverage the massive index of web pages to bring value to how you handle mobile pages. Google local mobile is absolutely a killer app. Context-based searching is of course important. But nothing really made me go "wow" like the stuff they are working on desktop-side.

Ultimately, I did enjoy finding out what goes on at Google though, and talking to a few of the attendees was at least as interesting as hearing from Google themselves. I'm sure once the London office gets a team together they'll be able to get some cool ideas worked out. But I think the wow here has to be "wow, Google are far behind the market innovators in the mobile field". I look forward to them proving me wrong!

Posted by savs at 5:53 PM

November 12, 2005

Safari caching problem

I've switched back to Safari from Firefox, as Firefox was just running too slow for me. I have one major problem with Safari though - it seems to be really bad at noticing changes in pages, and is caching too heavily. Is there any way I can reliably tell Safari to insist on downloading a page from scratch?
Posted by savs at 11:49 PM | Comments (4)

November 11, 2005

Still alive?

I am still alive, honest.

The first part of the week was spent dying a horrible and painful death from a terrifying life-threatening infectious disease (I had a bit of a cold and didn't feel too great).

Then I lost a day and a night to the joys of Ruby on Rails on Debian. Ready for prime time? Not without a LOT of pain. This is one framework that needs to grow up before I'd recommend it for general use; you need to be a genius sysadmin and no more than one step removed from divinity to have any hope of getting it to behave on a production server. More on that later, just as soon as I can write about it without letting out blood-curdling howls of anger and pain.

And then yesterday, wow. Google Open House, then Soup launch. Two London office opening parties in one night. More on Google Open House later, just as soon as I can turn my incoherent notes into something resembling an informed opinion.

Tomorrow, back to London with my nephew, taking him there for a day out, to do a bit of christmas shopping, but mostly to have an excuse to spend a few hours in Hamleys.

Meanwhile: sleep.

Posted by savs at 11:16 PM | Comments (2)

November 10, 2005

links for 2005-11-10

Posted by delicious at 10:17 PM

November 7, 2005

November 6, 2005

links for 2005-11-06

Posted by delicious at 10:24 PM

Cult of Mac

It was never like this with Windows or Linux.

Last night in the pub I found out that a friend of a friend is a Mac user. I was quite surprised - somehow I wasn't expecting it. Anyway, within seconds we were doing the now-familiar "what's on your Mac?" conversation, running through all the must-have applications, the top tips and recommendations.

A new twist to this is that web applications are starting to make it into the list, too. Flickr, del.icio.us, Movable Type ... the lines are being blurred. Not only do we love our apps, but now we love our sites too.

Anyway, this was the final push I needed to update my list of must-have Mac apps, this time as a delicious set of tags: mac software osx recommended. I think I got them all, let me know if you think anything is missing!

Posted by savs at 8:48 PM | Comments (2)

How to make a cup of tea

Boil the kettle. Place the tea bag in the mug, and just after the water stops boiling, pour it on. Leave to sit for 60 seconds or so, then remove the teabag. If you like sugar, add the sugar next. Finally, add milk to taste. Semi-skimmed, please.

The most important thing I learnt at university was how to make a really good cup of tea. If I recall correctly, a thread on making tea showed up in the uea.chat newsgroup, and the definitive description above was proposed, along with all the reasons why it should be done like that.

If I recall correctly:

  • You want hot but not boiling water. Boiling water releases unpleasant chemicals from the tea.
  • Add the sugar before the milk because it dissolves better.
  • There were some other facts, but I've forgotten them. Sorry.

See also a nice cup of tea. I write this now because I just made a bad cup of tea. The water had cooled in the kettle too much, and I was surprised at just how bad it tasted... so the method really does matter.

Posted by savs at 7:21 PM | Comments (1)

November 4, 2005

links for 2005-11-04

Posted by delicious at 10:17 PM

November 3, 2005

What am I bid for this cold, burnt pizza?

It's no secret that one of the essential foodstuffs for your average hard-working computer geek is a good old-fashioned pizza, There are some rules: it must be delivered (to reduce the risk of exercise minimise the time away from the keyboard), it must be laden with unhealthy cheese and grease (to increase the chance of heart attack give a junkfood-induced productive high), and it should ideally be served with alcohol (who needs a reason for that?).

Unfortunately, where I live there's only one real choice for decent delivered pizza, because Domino's refuse to deliver this far out. So I'm stuck with the franchise formerly known as Perfect Pizza, now known as Papa John's,

A couple of years ago, I swore to never again order from them. They took 2+ hours to deliver a pizza they promised would arrive in 40 minutes, and offered me money off the next pizza. They then conveniently "forgot" this compensation offer the next time I ordered.

Time heals all wounds, they say, so last week I decided to try out one of their newer pizzas, and to see if the service had improved any. They reckoned 50 minutes to deliver, and it showed up in about 1 hour and 10 minutes, so I decided that was close enough.

This week, still rushed off my feet, I decided to succumb to the guilty pleasure of pizza again, I phoned in my order at 18:20 (early enough to beat the rush, I'd hope), and was told it would take an hour to arrive. Good job I called early! When did it finally arrive? Just shy of 20:20, two hours after ordering. And it was, shall we say, not entirely hot. And just a little overcooked.

I know phoning and complaining has no benefit, since that route failed before. So this time, I'll probably write to the owner of the Papa John's brand, to let them know just what I think of the local franchise. Meanwhile, I guess I'd better quit eating pizza or start heading out to get it from Dominos. And if you all feel like Googlebombing Always Late, Usually cold Papa John's, who am I to stop you?

Posted by savs at 8:34 PM

podcastfu

Podcast Dir FuI think Apple might still have a few glitches to work out with the iTMS podcast directory. This screenshot is what I got today when I tried to view it.

It seems to be behaving again now.

Posted by savs at 2:00 PM

November 2, 2005

This week's addiction

Rocketboom...
Posted by savs at 10:20 PM

Safari upgrade

Nwolb Safari 202The version number for Safari was upgraded in OS X 10.4.3, which means the inevitable round of "Natwest bank are crap" posts from me. Happy days.
Posted by savs at 3:41 PM

MySQL is a PITA

My views on MySQL are fairly well-known. It makes me sick, and it sucks.

Herein some further evidence.

DROP DATABASE foo;
ERROR 1010 at line 1: Error dropping database (can't rmdir './foo/', errno: 17)

ls -l foo
.DS_Store

Lovely! It'll delete all the data, but put a file in the data directory it doesn't expect, and it breaks.

You could argue that actually this is Apple's fault for sprinkling those damned .DS_Store files all over the place, but equally a version of MySQL packaged for OS X ought to handle this case, no?

Admittedly this is an old version of MySQL, but I still felt the need to rant. I feel much better now, thank you.

Posted by savs at 11:28 AM

November 1, 2005

Front Woe

Aww, c'mon Apple ... the Mac OS X 10.4.3 Update breaks Front Row on my Powerbook.

Given how half-baked the support for Video podcasts is in iTunes (for example, it plays videos in the Album Art preview window in the bottom-left by default; you have to start the video then click on it to get it to play in a separate window), this is a major PITA. I was quite enjoying watching videos via the altogether more usable Front Row GUI.

For now I'll resort to VLC, but it's about time Apple started working with the users instead of against the users ... why not provide Front Row as part of 10.4.3?

Update: Marcus to the rescue once more! By editing the openfrontrow Applescript, you can get Front Row to run again. Excellent!

Posted by savs at 6:02 PM

Cheesey featherfrack

via stega:

A. Follow the instructions to find your new name.

B. Once you have your new name, put it in the subject box and forward it to friends and family and co-workers. Don't forget to forward it back to the person who sent it to you, so they know you participated. And don't go all adult - a senior manager is now known far and wide as Dorky Gizzardsniffer. The following in excerpted from a children's book, "Captain Underpants And the Perilous Plot Professor Poopypants" by Dave Pilkey, in which the evil Professor forces everyone to assume new names...

1. Use the third letter of your first name to determine your new first name:
a = snickle
b = doombah
c = goober
d = cheesey
e = crusty
f = greasy
g = dumbo
h = farcus
i = dorky
j = doofus
k = funky
l = boobie
m = sleezy
n = sloopy
o = fluffy
p = stinky
q = slimy
r = dorfus
s = snooty
t = tootsie
u = dipsy
v = sneezy
w = liver
x = skippy
y = dinky
z = zippy

2. Use the second letter of your last name to determine the first half of your new last name:
a = dippin
b = feather
c = batty
d = burger
e = chicken
f = barffy
g = lizard
h = waffle
i = farkle
j = monkey
k = flippin
l = fricken
m = bubble
n = rhino
o = potty
p = hamster
q = buckle
r = gizzard
s = lickin
t = snickle
u = chuckle
v = pickle
w = hubble
x = dingle
y = gorilla
z = girdle

3. Use the third letter of your last name to determine the second half of your new last name:
a = butt
b = boob
c = face
d = nose
e = hump
f = breath
g = pants
h = shorts
i = lips
j = honker
k = head
l = tush
m = chunks
n = dunkin
o = brains
p = biscuits
q = toes
r = doodle
s = fanny
t = sniffer
u = sprinkles
v = frack
w = squirt
x = humperdinck
y = hiney
z = juice

That's actually quite funny - my cousin was always called "cheese" by his mates. The perils of the surname 'Savory'.
Posted by savs at 8:38 AM