Improved sfDateValidator for Symfony 1.0 - new download link

Wednesday, May 7, 2008

Sometime during last month, the server where my improved sfDateValidator for Symfony 1.0 was hosted went down. Although over a year passed since I wrote it, I’m quite pleased that there are still some people who are interested in it.

Of course there’s the ticket in Symfony’s Trac with the files attached to it, but the attached php class is the wrong one. In order to use it, you had to apply the attached patch manually (which I guess caused some confusion).

However, I ran the unit test for the improved sfDateValidator against Symfony 1.0.14, and it still works very well. So, here’s the new download link:

Download the improved sfDateValidator for Symfony 1.0

You might want to head over to the old post on Symfoniac for a quick usage example.

1 Comment

Merging with git-pull

Tuesday, May 6, 2008

The git-pull command is basically a shortcut for:

git-fetch && git-merge origin

The fetch gets the changes from the remote repository, but does not merge them with your local checkout yet. You can examine these changes using origin as the reference, and merge them into your master branch.

The git-fetch part is optional. You can pass . (current directory) to it and merge local branches.

git-pull . refactor
git-merge refactor

Both commands will do the same: merge the refactor branch.

Git Configuration

Friday, May 2, 2008

Here are some useful configuration options for Git. Some of them, like the Bash completion, are OS X specific but should also work if you adjust the paths according to your system of choice.

Install with MacPorts:

sudo port install git-core +svn +bash_completion

Bash completion:

cp /opt/local/etc/bash_completion.d/git ~/.git-bash-completion.sh
echo "[ -f ~/.git-bash-completion.sh ] && . ~/.git-bash-completion.sh" >> ~/.bash_profile
. ~/.bash_profile

Global ignore file:

echo ".DS_Store" >> ~/.gitignore
git config --global core.excludesfile ~/.gitignore

SVN-like shortcuts for often used commands:

git config --global alias.st status
git config --global alias.ci commit
git config --global alias.co checkout
git config --global alias.br branch

Information about the author/commiter:

git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com

Colorized output:

git config --global color.branch auto
git config --global color.diff auto
git config --global color.interactive auto
git config --global color.status auto

TextMate as the default editor:

git config --global core.editor "mate -w"

Opendiff (FileMerge) to resolve merge conflicts:

git config --global merge.tool opendiff

Change the font in gitk: Open ~/.gitk and add:

set mainfont {Monaco 12}
set textfont {Monaco 12}
set uifont {Monaco 12}

1 Comment

Install Django with Git

Wednesday, April 30, 2008

Although Brian Rosner did a very good Screencast on installing and using Git with Django, there are sadly no Show Notes available. This makes installing Django from Git a quite time-consuming task, if you haven’t memorized the commands.

While writing down the commands for further use, I noticed that there’s a faster way than cloning the official SVN repository by using an unofficial Git mirror. Later on, I wrote a small Bash script to automate the Django-from-Git installation, which you can download below.

Official SVN repository

First, clone the repository with:

git svn clone -s http://code.djangoproject.com/svn/django django

navigate to the django folder and run:

git gc

to cleanup unnecessary files and optimize the local repository. Finally, reset the master branch to point to trunk:

git reset --hard trunk

Git mirror

Instead of going thrugh the time-consuming task of cloning the official SVN repository, there’s an faster and easier way. Matthias Kestenholz was so kind to set up a Git mirror for Django, which is updated hourly.

Just use the git clone command, as with any other Git repository:

git clone git://spinlock.ch/pub/git/django/django.git django.git

Bash script

To save some time on the next “Django from Git” installation, I wrote a simple Bash script to automate this task.

The script will clone the unofficial Git mirror in a folder called django.git and create the necessary symbolic links to install Django: 

  1. django folder to the python site-packages directory.
  2. django-admin.py file to a directory on the system path (the script uses /usr/bin).

Download django-git-install

After the download, you need to make the script executable:

chmod u+x django-git-install.sh

The script expects the installation directory as the first parameter:

Usage: django-git-install.sh target-directory

For example, to install Django into /usr/lib/django.git, execute:

sudo ./django-git-install.sh /usr/lib

Benchmark: MacBook with WD Scorpio hdd

Tuesday, April 22, 2008

I recently upgraded my MacBook’s hard drive, the Seagate Momentus 5400.3 160GB (ST9160821AS), to a Western Digital Scorpio 250GB (WD2500BEVS) and did a quick benchmark to see how much performance would change over the old hard drive.

Listed below are the average scores of 6 XBench Memory Test runs.

Benchmark

Seagate Momentus: 41.47 MB/sec
Western Digital Scorpio: 55.51 MB/sec

Seagate Momentus: 38.66 MB/sec
Western Digital Scorpio: 51.31 MB/sec

Seagate Momentus: 17.46 MB/sec
Western Digital Scorpio: 13.59 MB/sec

Seagate Momentus: 38.87 MB/sec
Western Digital Scorpio: 53.82 MB/sec

Seagate Momentus: 0.72 MB/sec
Western Digital Scorpio: 1.88 MB/sec

Seagate Momentus: 20.81 MB/sec
Western Digital Scorpio: 33.89 MB/sec

Seagate Momentus: 0.47 MB/sec
Western Digital Scorpio: 0.50 MB/sec

Seagate Momentus: 16.87 MB/sec
Western Digital Scorpio: 20.65 MB/sec

Temperature/Noise

The temperature stayed the same, at 32°C. There was no noticeable increase in loudness with the new hard drive.

In the first moment I noticed that the WD Scorpio is vibrating a little more than the Seagate Momentus (the hard drive’s location is directly under the left hand). However, it became pretty normal after half-an-hour.

Conclusion

There was only one test (sequential uncached read with 4K blocks) where the WD Scorpio was slightly slower than the Seagate Momentus, but all the other tests show a massive improvement.

There were quite a few people told me that upgrading the MacBook’s default hard drive would definitely be worth it, but I never expected it to be so clear. All in all, I’m happy with the new hard drive.

RuPy 2008

Wednesday, April 16, 2008

Last weekend I attended the RuPy (Ruby & Python) conference in Poznan (Poland).

The program was splitted into simultaneously held Ruby and Python talks. For example: while the “TDD in Rails” talk in room A, a “TDD in Python” talk was held in room B. Language-independent talks, like “Business Natural Languages”, were held in one room.

Talks

I missed half of Micheal Foord’s talk on “Programming the Browser with IronPython and Silverlight” due to my late arriving. However, the stuff which I saw gave me some nice insights into what IronPython and Silverlight are capable of.

Watching the adoption of Silverlight and development of Moonlight (Silverlight for linux) is quite interesting, especially since Microsoft made a deal to put Silverlight on the official Beijing Olympics website

  

(Photos taken by ukasbadu, more photos are available on flickr under the rupy2008 tag)

The next talk by Zed Shaw about “Correlations and Conclusions” was really funny but also very informative. He benchmarked Mongrel against web.py and inserted the data into R. R seems like really nice tool for statistical data and once you get used to it’s weird syntax there are certainly a lot of things you can do with it.

What I didn’t know was that httperf is more superior to ab and used for serious stuff, while ab is mostly okay for quick’n'dirty benchmarks.

The presentation itself was done using latex-beamer and generated out of a YAML file - a quite interesting concept which Zed Shaw is going to describe further in his blog.

Jonathan Hartley, who works together with Micheal Foord at Resolver Systems, held a great talk about Test-driven development and shared his experiences over the past few years. A really interesting fact is the ratio of test code to product, which is 4:1 - meaning that there are four lines of test code for each line of product code.

Business Natural Languages (a Domain Specific Language for empowering subject matter experts) were presented by Jay Fields from ThoughtWorks. The whole point in a BNL is to allow the customer to change the applications behaviour without involving the developer. It’s definately worth a look for some bigger projects.

Bottom line

The organization was perfect and the choosen topics very interesting. The only negative thing was actually lunch, which was horrible (and not very warm).

However, it was a great conference which I can only highly recommend to everyone interested.

2 Comments

Flash messages are for doing notices and alerts

Wednesday, April 9, 2008

Ever since Ruby on Rails introduced flash messages, it has become a widely popular feature which got ported to various other frameworks such as Symfony and is also available as a custom middleware for Django.

The RoR API documentation describes a flash as a:

“… way to pass temporary objects between actions. Anything you place in the flash will be exposed to the very next action and then cleared out. This is a great way of doing notices and alerts …”

However, many developers tend to use it for more than just “doing notices and alerts”, like passing  critical variables. This might not be a functional idea in the day and age of Tabbed Browsing since request variables like flash attributes are set browser-wide, each new tab on the same controller causes the flash value to be overwritten.

Meaning that if you have 5 tabs opened and each tab points to the same page (but has different request variables) the same flash attribute gets overwritten multiple times. The flash value from the most recent opened tab is used for all 5 tabs. If the next action of your application relies on that specific flash attribute, it might produce some unexpected results.

Example: A Blog

Think of a simple blog which shows a listing of various entries on the frontpage. With a click on an entry, it simply gets shown with a comment form. The entry id for the comment form is passed via a flash rather than a hidden field.

If the user opens up multiple blog entries from the frontpage in new tabs, each tab sets the entry id flash again. When the first tab gets opened, the flash attribute has the value of the last opened entry - a written comment would be associated with the last opened entry rather than the first opened entry.

Conclusion: Sticking to hidden fields and validating it’s value properly might (still) be the best idea.

Validating Checkboxes and Radiobuttons in Symfony

Wednesday, April 2, 2008

Months ago I wrote about the validation of checkboxes in Symfony and how it could fill your database with wrong values.

I recommended downloading, or writing, a small validator which checked if the value of the checkbox is zero or one. But there’s a much simpler solution to this problem.

If you use a numerical value for your radiobuttons/checkboxes, simply call the sfNumberValidator with zero as an minmum and one as an maximum.

tos:
  sfNumberValidator:
    min: 0
    max: 1

If you use strings, such as ‘male’ or ‘female’ for a gender radiobutton, the sfStringValidator is the right choice:

sfStringValidator:
  values: ['male', 'female']
  value_error: Invalid value

Symfony + MySQL to Django + PostgreSQL

Wednesday, March 26, 2008

While recently migrating Tschitschereengreen.com from Symfony to Django plus changing the database backend from MySQL to PostgreSQL, there were mainly two tasks more time-consuming than I’ve had thought beforehand:

SQL dump

The old database used a latin1 encoding for the database fields and utf-8 as the server and client connection encoding. With these settings, even trying to get a correctly encoded database dump from phpMyAdmin is a bad idea.

Using mysqldump with an explicitly specified character-set is much better:

mysqldump … –default-character-set=latin1 –skip-set-charset dbname > dump.sql

MySQL to PostgreSQL with JSON

After realizing that changing a MySQL dump to a valid PostgreSQL dump might take some time, Django’s ability to import and export database fixtures in JSON was a great alternative.

There were, however, a few corrections needed in order to import the data in PostgreSQL:

  1. Date fields
    “0000-00-00 00:00:00″ might be valid MySQL datetime value, but it ain’t so in PostgreSQL. To import the data it is needed to replace such dates with valid ones like “1970-01-01 00:00:01″.
  2. Boolean fields
    MySQL doesn’t support real boolean fields and instead uses tinyint. PostgreSQL, on the other hand, supports real boolean fields and doesn’t accept “0″ or “1″ as valid boolean values. Replacing “0″ with “”alse” and “1″ with “true” will help in this case.

Pseudo Closed Beta

Wednesday, February 27, 2008

Web2.0 services spring up like mushrooms nowadays, most users can’t even keep up anymore. In order to stand out from the crowd, services are now going the way of pseudo closed beta.

Do you know these pesky letters which land in your mailbox from time to time, and claim that you were selected to take part in some special lottery? Yeah, I bet you love them as much as I do - a pseudo closed beta is like that.

Instead of sending you spam mails, which will be ignored anyways, new services give away a bunch of invites to tech weblogs that promise to write about the service. For other users, there’s a form on the website in which you can enter your email address and, if you’re lucky, get an invite code.

But here’s the trick: Everyone gets an invite.

Sometime later an email arrives with the invite code in it: This must be your lucky day - you immediately fire up your browser, register and start testing everything out thoroughly.

From the web service’s standpoint, the advantages are simple:

But would you care that much if it were a open beta?