Fahrenheit 451: intriguing

October 2nd, 2007

It's always unpredictable when an idea is developed literally to see just how it will be interpreted. Fahrenheit 451's literalism really goes a long way, and eventually to the point where it becomes silly. But it's an interesting plot all the same.

If you've familiarized yourself with 1984 or any derivative thereof (like Equilibrium), you will find yourself right at home. It's hard to know to what extent Ray Bradbury's vision was recreated faithfully, but the odd thing here is the lack of a totalitarian regime. The one authority we relate to is the Fire Department, whose function it is to burn books. The rationale is that books make people unhappy, and therefore they must be destroyed. Mkay.

From 1984 they reused the tv concept, as a propaganda delivery device (not terribly far fetched in our world anyhow). This is also the only reference to a regime in the plot, where they call the nation a family and citizens cousins. But the tvs do not spy on people. 1984 is truly totalitarian in how every aspect of life is controlled. Here it's just the books they don't like. They bring in the owners to be questioned, but there is no sense of torture or death row punishment for the offense.

The culmination of rebellion, is the notion that every person who loves books picks one and commits it entirely to memory. So that instead of *having* the book they *know* the book. This is where the literalism runs wild. They even take it as far as if a book is published in two volumes then two people will learn it and each recite one volume. This idea is put into practice in a pretty odd way, as we just see people wandering around the woods reciting books without much concern for where they are spending the night or how they plan to feed themselves. I can't say that I see the immediate benefit of this lifestyle. After all it's not the literal content of books that is useful, it is the wisdom.

I get the feeling that Bradbury was much in awe of Orwell and decided not to push the envelope here. Orwell's society is masterfully crafted, whereas Bradbury seems to have limited himself to some reasonable subset without trying to connect as many dots. Of course, one can ask oneself whether topping Orwell is even possible. But not trying obviously won't get you there.

An interesting story, but a bit half baked.

happiness, you'll know it when you see it

October 1st, 2007

Why? I have no idea. It's a symptom, haven't found the cause yet. The transformation is practically asymptotic, that's for sure. :D

the unhappy reality of upgrades

September 25th, 2007

It struck me today that as coders we do what we can to wrap our nasty, complicated code in a neat package that the user will love. They don't realize, and we don't want them to know, just how convoluted and messy the stuff is on the inside. And this holds up for long periods of time. But there comes a time when our neat little illusion cracks up and the ugliness comes into view. Bugs expose it sometimes, but upgrades do this with immaculate regularity.

Why today? Because Wordpress 2.3 was dropped today. The Wordpress people decided to toss out categories in favor of a wonderfully engineered (isn't that what we always believe?) taxonomy system. With the immediate consequence that any code that has anything to do with categories would break. That's two of my plugins. Clearly these guys are not Windows users. Microsoft's Patch and Play strategy with Windows has kept *a lot* of companies happy, as they continually strive to emulate their old bugs to accommodate programs that were written to cope with them. This has seriously handicapped Windows from making progress, because they keep pulling that huge sack of legacy code going back to probably Win3.1 (with Workgroups, yay!).

Posts used to be related to Categories with an in-between table, the classic N:M relational idiom. Now there are 4 tables, all related to each other in interesting ways. It took me quite a while to crack this code. This was introduced to add tagging support, which is quite the annoyance, because I have no interest in tagging. I find it a useless errand. And, of course, for those not tagging from the beginning you always come back to having to post-tag 600 old posts. Forget it.

Tools always help a lot, but it's very difficult to capture all the nuances, and in many cases human review is necessary anyway (particularly when themes change). And this is the sad reality of it. While minor upgrades are now handled routinely, bigger changes will always cause problems.

The End of Faith

September 24th, 2007

I find that Sam Harris is a more articulate critic of religion than Richard Dawkins, who is clearly more hostile. His two books The End of Faith and Letter to a Christian Nation raise a lot interesting issues. The latter is not particularly interesting, but the former presents much insight.

The text is actually quite comprehensive at times, and piecemeal reading doesn't do it justice. I think he makes excellent points about the suffocating role of religion as opposed to progress and the evolution of knowledge. And his criticism of religion as a driving force in politics and policy making leaves little to dispute. Furthermore, the distinction of religions in terms of their values is a very relevant point. As is the condemnation of the taboo against criticizing irrational beliefs.

But what ultimately drives his "war on religion" is the premise that unless we do something right now we're going to destroy ourselves. It would be perfectly fine to make all the arguments he does as a crusade for intellectual honesty. And there is certainly enough social and political justification for it. But his bottom line is a doomsday scenario which I find rather extreme.

For more on this (and yes, he's an excellent speaker), youtube it:

The talks are rather focused on the struggle between religion and rationality, they don't go into his ideas about world destruction that much.

wordpress update script

September 22nd, 2007

Aah, the free world. It's beautiful, you have frequent releases, the code is there for you, everything's wondeful. But for web apps like Wordpress the maintenance cycle is less convenient than with desktop applications. There's no package manager to handle updates for you. Yes, that's the downside.

I've upgraded Wordpress now 3-4 times and I'm already sick of it. It's so mechanical. I've also rehearsed the cycle a bunch of times with vBulletin. Well, compared to the tidy and elegant Wordpress, vBulletin is a monster. But the upgrade issues are the same, albeit less painful now. I should have done this years ago, but now at least I have an organized way of handling these upgrades.

Here's the rationale. You download some Wordpress version from wordpress.org and install it. This we call the reference version. Then you hack on it a bit. You install plugins, maybe you hack the source a little. You change the theme a bit. And in the course of using Wordpress you also upload files with posts sometimes, for instance to include pictures with your posts.

wordpress_upgrade.png

So now the state of your Wordpress tree has changed a bit, you've added some files, maybe you've changed some files. Basically, it's different from the vanilla version. This we call mine. And now you've decided that the next Wordpress version has some nice features and bug fixes you want. This version we call latest.

You want to upgrade, but there is no upgrade path from mine to latest, because the Wordpress people can't know what you did with your local version. Upgrading from mine to latest may not be safe, it hasn't been tried.

wordpress_upgrade2.pngOf course, this sort of problem is nothing new. Coders have faced it forever. And that's why we have things like diff and patch, standard Unix tools. So here's how to upgrade safely.

  • First roll back the local changes so that we return to the reference version.
  • Save the local modifications.
  • Do a standard Wordpress upgrade going from ref to latest.
  • Re-apply, if possible, the local modifications.

And this replicates exactly what you would do manually if you wanted to be sure that the upgrade doesn't break anything. Just that it's a lot of hassle to do by hand. The upgrade is done offsite, so your blog continues to run in the meantime. And once you've upgraded, you can just move it into the right location.

In the event that merging diff and latest does not succeed, you have a list of the patches and files so that you know exactly which ones didn't succeed.

So far I've used it to do two updates, 2.2.1->2.2.2, 2.2.2->2.2.3, without any hiccups.

#!/bin/bash

# >> 0.3
# added file/dir permission tracking
# added hint for failed file merges
# added hint for failed patches

echo<<header "
################################################################################
#                                                                              #
#                      Wordpress Updater / version 0.3                         #
#                   Martin Matusiak ~ numerodix@gmail.com                      #
#                                                                              #
#  Description: A script to automate [part of] the Wordpress update cycle, by  #
#  finding my modifications to the codebase (mine), diffing them against the   #
#  official codebase (ref), and migrating files and patches to the latest      #
#  version (latest).                                                           #
#                                                                              #
#  Warning: Upgrading to a new version will probably not always work           #
#  seamlessly, depending on what changes have occurred. Do not use this as a   #
#  substitute for following the official upgrade instructions. Furthermore, if #
#  you don't understand what this script does, you probably shouldn't use it.  #
#  Also, it's always a good idea to backup your files before you begin.        #
#                                                                              #
#  Licensed under the GNU Public License, version 3.                           #
#                                                                              #
################################################################################
"
header

### <Configutation>

wpmine="/home/user/www/numerodix/blog"
version_file="${wpmine}/wp-includes/version.php"
wordpress_baseurl="http://wordpress.org"
temp_path="/home/user/t"

### </Configuration>


echo -e "Pausing 10 seconds... (Ctrl+C to abort)\007"
sleep 10


msg() {
fill=$(for i in $(seq 1 $((76 - ${#1}))); do echo -n " "; done)
echo<<msg "
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  ${1}${fill}+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"
msg
}


if ! mkdir -p $temp_path; then
	echo "$temp_path not created"; exit 1
fi

msg "Checking installed version... "
if [ -f $version_file ]; then 
	ref=$(cat $version_file | grep "\$wp_version" | tr -d " _$'';=[:alpha:]")
	echo $ref
else
	echo "$version_file not found"; exit 1
fi


msg "Fetching version $ref... "
[ -f $temp_path/wordpress-$ref.tar.gz ] && rm $temp_path/wordpress-$ref.tar.gz
if wget -q -P $temp_path $wordpress_baseurl/wordpress-$ref.tar.gz; then
	echo "downloaded to $temp_path"
else
	echo "could not fetch $wordpress_baseurl/wordpress-$ref.tar.gz"; exit 1
fi


msg "Unpacking reference version $ref... "
[ -d $temp_path/wordpress-$ref ] && rm -rf $temp_path/wordpress-$ref
if (cd $temp_path && tar zxf wordpress-$ref.tar.gz && mv wordpress wordpress-$ref); then
	echo "unpacked to $temp_path/wordpress-$ref"
else
	echo "failed"; exit 1
fi

wpref="$temp_path/wordpress-$ref"


msg "Diffing codebase... "
( cd $wpref && find . -type f | sed "s|\./||g" | sort > $temp_path/files-$ref-ref ) &&
( cd $wpmine && find . -type f | sed "s|\./||g" | sort > $temp_path/files-$ref-mine ) &&
diff $temp_path/files-$ref-ref $temp_path/files-$ref-mine > $temp_path/diff
if [[ $? < 2 ]]; then
	echo "diff written to $temp_path/diff"
else
	echo "failed"; exit 1
fi


msg "Recording my file/dir permissions..."
cd $wpmine && \
find . -exec ls -ld --time-style=+%s {} \; | sed "s|\./||g" | sort -k 7 \
> $temp_path/files-$ref-mine.perms
if [[ $? == 0 ]]; then
	echo "written to $temp_path/files-$ref-mine.perms"
else
	echo "failed"; exit 1
fi


msg "Listing files added/removed... "
( cat $temp_path/diff | grep "^>" | awk '{ print $2 }' > $temp_path/only_mine ) &&
( cat $temp_path/diff | grep "^<" | awk '{ print $2 }' > $temp_path/only_ref ) &&
( cat $temp_path/only_mine > $temp_path/not_common ) &&
( cat $temp_path/only_ref >> $temp_path/not_common )
if [[ $? == 0 ]]; then
	echo "mine only files written to $temp_path/only_mine"
	echo "ref only files written to $temp_path/only_ref"
else
	echo "failed"; exit 1
fi


msg "Listing files changed... "
[ -f $temp_path/changed ] && rm $temp_path/changed && touch $temp_path/changed
for i in $(cat $temp_path/files-$ref-ref); do
	if ! grep -x $i $temp_path/not_common >/dev/null; then
		if ! diff -q $temp_path/wordpress-$ref/$i $wpmine/$i >/dev/null; then
			echo $i >> $temp_path/changed
		fi
	fi
done
if [[ $(wc -l < $temp_path/changed) == "0" ]]; then
	echo "No changes detected"
else
	echo "Files changed written to $temp_path/changed"
fi


msg "Writing individual diffs... "
[ -d $temp_path/diffs ] && rm -rf $temp_path/diffs
mkdir -p $temp_path/diffs
for i in $(cat $temp_path/changed); do
	e=$( echo $i | sed "s|\./||g" | tr "/" "." )
	diff -u $temp_path/wordpress-$ref/$i $wpmine/$i > $temp_path/diffs/$e
done
ds=$(ls $temp_path/diffs | wc -l)
echo "$ds diffs in $temp_path/diffs"


msg "Fetching latest version... "
[ -f $temp_path/latest.tar.gz ] && rm $temp_path/latest.tar.gz
if wget -q -P $temp_path $wordpress_baseurl/latest.tar.gz; then
	echo "downloaded to $temp_path"
else
	echo "could not fetch $wordpress_baseurl/latest.tar.gz"; exit 1
fi


msg "Unpacking latest version... "
[ -d $temp_path/wordpress-latest ] && rm -rf $temp_path/wordpress-latest
if (cd $temp_path && tar zxf latest.tar.gz && mv wordpress wordpress-latest); then
	echo "unpacked to $temp_path/wordpress-latest"
else
	echo "failed"; exit 1
fi

wplatest="$temp_path/wordpress-latest"


msg "Trying to patch diffs... "
post=$(echo $wpmine | tr -d "/")
patch_level=$(( ${#wpmine} - ${#post} ))
[ -f $temp_path/patches.failed ] && rm $temp_path/patches.failed
for i in $(ls $temp_path/diffs); do
	cd $wplatest && patch -p$patch_level < $temp_path/diffs/$i
	if [[ $? != 0 ]]; then
		echo $temp_path/diffs/$i >> $temp_path/patches.failed
	fi
done


msg "Merging in my files... "
[ -f $temp_path/file-merge.failed ] && rm $temp_path/file-merge.failed
for i in $(cat $temp_path/only_mine); do
	d=$(dirname	$wplatest/$i)
	mkdir -p $d
	if [ -e $wplatest/$i ]; then 
		( echo "file already exists: $i"; 
		echo $i >> $temp_path/file-merge.failed )
	else
		( echo "merging: $i" && cp -a $wpmine/$i $wplatest/$i )
	fi
done


msg "Merging file/dir permissions..."
while read line; do
	f=$(echo $line | awk '{ print $7 }')
	p=$(echo $line | awk '{ print $1 }'); p=${p:1:9}
	u=$(echo ${p:0:3} | tr -d '-')
	g=$(echo ${p:3:3} | tr -d '-')
	o=$(echo ${p:6:3} | tr -d '-')
	if [ -e $wplatest/$f ]; then 
		echo "setting: $p $f"
		chmod u=$u $wplatest/$f
		chmod g=$g $wplatest/$f
		chmod o=$o $wplatest/$f
	fi
done < $temp_path/files-$ref-mine.perms


msg "Removing files I deleted... "
for i in $(cat $temp_path/only_ref); do
	[ -f $wplatest/$i ] && (echo "removing: $i" && rm $wplatest/$i)
done


msg "Complete"

[ -f $temp_path/patches.failed ] &&
echo "Some of my patches failed to apply, listed in $temp_path/patches.failed"

[ -f $temp_path/file-merge.failed ] &&
echo "Some of my files failed to merge, listed in $temp_path/file-merge.failed"

echo<<close "
The upgraded version is in $wplatest

To install the new version you'll want to do something like this:
  mv $wpmine ${wpmine}.old
  mv $wplatest $wpmine

Afterwards you can remove the temporary dir $temp_path

If the new version provides any php upgrades scripts (to upgrade the 
database), now would be a good time to run them"
close

Another option would be to use Subversion and just update between stable tags, but then again I don't have that on the server and most hosts probably don't install it. But the Subversion method and this one are functionally equivalent, with the small exception that this upgrade is done offsite while the Subversion way would typically (but not necessarily) be a live upgrade.