Wednesday, 23 April 2008

Facebook Chat Firefox Plugin

FacebookFacebook finally released their chat functionality to all their users today. It's fantastic! I quickly came to the conclusion that it did have one major flaw: you have to be on the Facebook page to see any incoming messages. So to solve this, I quickly knocked up a Firefox add-on to alert you if you have any new chat messages. You can download it here.Firefox Facebook Chat Add-on Screenshot

It uses the built-in Firefox alert system, so you'll need Firefox 3 on OS X (for Growl) and 2 for other OSs. At the moment you also have to leave the Facebook page open, if I have time later, I'll deal with this so that you can close the Facebook page.

PLUG: Donate 2 Date is my Facebook app. It helps raise money for charity by setting people up on dates. Check it out!

Sunday, 20 April 2008

Building A Legacy LAMP Stack

LAMPThere are many live sites on the web that were written in PHP3. In case you ever need to set up an environment for one, here's how:
  1. Download and compile MySQL 4. You can get the source in from the archives on the MySQL website.
  2. Download Apache 1.3, take a look here. As well as setting the prefix in the configure step, you'll need to enable mod_so with --enable-module=so.
  3. Download PHP3, you can find it here. Now here comes the tricky bit:
    • The MySQL 4 client libraries don't include DROP DATABASE and CREATE DATABASE bindings, so we need to remove these from the PHP source. Grep for mysql_drop_db and mysql_create_db and comment out the relevant lines and functions.
    • Set the MYSQL_LIB and MYSQL_INC environment variables before running configure. The PHP 3 configure doesn't pick up the default MySQL 4 paths (MYSQL_LIB=/usr/local/mysql/lib/mysql and MYSQL_INC=/usr/local/mysql/include/mysql).
    • Continue with a normal configure, make and make install, building a shared object for Apache (see the INSTALL file).
  4. One last thing. After following the INSTALL file instructions for editing the httpd.conf, you may need to add a FileHandler for php files as well as php3 files.
Note: This is not a long term strategy. PHP 3, MySQL 4 and Apache 1.3 are not actively maintained so they're bound to be riddled with problems (including security holes). Best to update as soon possible!

Thursday, 3 April 2008

Zen of Programming

ZenProgramming is a difficult discipline. It requires a phenomenal knowledge of difficult technologies: (usually several) programming languages, operating systems, knowledge of hardware, protocols, databases, etc. It takes years of using them to build up the know-how to use them all effectively to solve something (and isn't that the point of programming). However, knowledge and understanding are not enough. Having a certain type of brain helps a lot too. Most good programmers are excellent logical thinkers and have a solid background in maths.

So you've got a few years experience, you know a couple of languages and can bash out code with your eyes closed. This is the point where you start worrying about the quality of your code. How buggy is it? How robust is it? How maintainable is it? Dealing these problems is not like before - there is no solution, but there are ways you can cope. The Zen of Programming:
  1. Re-read what you just coded - before running it / compiling it.
  2. Think as far ahead as you can. But don't spend so long that you don't get anything done.
  3. Refactor a lot.
  4. Try and automate your testing.
  5. Re-read the documentation of a language / library after you become competent in it.
Most of these points boil down to having patience. If you are naturally so, then you probably do most of these anyway. Otherwise, it is very much worth forcing yourself to change your style - you will save time and your code will be much, much better.

Tuesday, 1 April 2008

Handling International Dialling Codes (in Python)

The website I'm working on at the moment collects a user's phone number. This must work with phones from any country and each number must be converted into a standard format so that it can be used with an SMS API. For example, the phone number +44 (0)7912345678 would become 447912345678.To make it as easy as possible for the user to not make a mistake, the international dialling code is in a


<select name="dialling_code">
<option
for="country, dialling_code, ndd in internationalDiallingCodes"
value="${dialling_code}">
${country} (+${dialling_code})
</option>
</select>


When the form is submitted, we need another function to turn the dialling code plus the rest of the number into the right format (note: this is also where internationalDiallingCodes comes from):


def makeStandardPhoneNumber(internationalCode, rest):
"""
Make a standard phone number by appending rest to the
internationalCode. Check the first digits rest to see if they
match the NDD which must be removed from the number.
i.e. 0 in the UK
Example: makeStandardPhoneNumber('44', '073749135381')
-> '4473749135381'
"""
# Get the NDD code for this internationalCode
ndd = getNDD(internationalCode)
# if the country has an NDD, check for it and remove if it
# exists
if ndd is not None:
index = len(ndd)
if rest[:index] == ndd:
rest = rest[index:]
result = internationalCode + rest
return result

def getNDD(internationalCode):
for country, iCode, ndd in internationalDiallingCodes:
if iCode == internationalCode:
return ndd
return None

internationalDiallingCodes = [ ("Afghanistan ", "93", "0"), ("Albania", "355", "0"), ("Algeria", "213", "7"), ("Andorra", "376", None), ("Angola", "244", "0"),...]

You can download the python source file here. It is trivial to modify the functions to put the phone number into the format you want. If you needed a performance boost, this function could be optimised by inversing the index on internationalDiallingCodes.

* Also:
You can download a CSV of phone codes here. That should make it easy to include them in any program. These do not include satellite phone companies.