Using Livedrive on your iPhone

Livedrive (the company I work for) launched their iPhone app today that lets you access files you’ve backed up with Livedrive from anywhere. I think it’s genuinely really cool – checkout the intro video below…

Recursively Getting Directory Contents in C#

Have you ever wanted an easy way to get all of the contents of a directory into one array, regardless of how many levels of subfolders there are? This is a task for my favourite kind of programming – nested loops!

The following function will do the job nicely:

private static void listDirectoryNest(string path, ref List<string> currentList, bool includedirs)
{

    foreach (string dir in Directory.GetDirectories(path))
    {
        listDirectoryNest(dir + "\\", ref currentList, includedirs);
        if (includedirs)
            currentList.Add(dir + "\\");
    }

    foreach (string file in Directory.GetFiles(path))
    {
        currentList.Add(file);
    }

}

This function takes the string path which defines where the nesting is to start, for example e:\documents. It then takes the reference currentList which is a generic string list. After the function is run this string list will contain all of the files within the original path (including those in subfolders). The final variable, includedirs defines whether or not to include directories in the currentList output. If you set this variable to true then you can determine which entries in currentList are directories by checking if they end with the \ character.

This is an example of how to call the function above:

List<string> output = new List<string>();

listDirectoryNest("e:\\documents", ref output, true);

After running that code, output will contain all of the contents of e:\documents\, including subfolders, in a format like:

  • e:\documents\something.doc
  • e:\documents\something-else.xls
  • e:\documents\some subfolder\
  • e:\documents\some subfolder\subdocument.xls
  • e:\documents\my pictures\
  • e:\documents\my pictures\photo.jpg

Photographing a Wedding

I had the honour of photographing a friend’s wedding this weekend. These are some of my favourite shots, but the rest can be found at Tim and Jane’s Wedding.

From Tim and Jane's Wedding – Getting Ready
From Tim and Jane's Wedding – The Ceremony
From Tim and Jane's Wedding – The Ceremony
From Tim and Jane's Wedding – The Ceremony
From Tim and Jane's Wedding – The Ceremony
From Tim and Jane's Wedding – The Reception
From Tim and Jane's Wedding – The Reception
From Tim and Jane's Wedding – The Reception
From Tim and Jane's Wedding – The Reception

However there were some fantastic moment’s all round, including my wife’s red taxi being the main weddng car, a wonderful garden bar, and even an impromptu live performance by the great Mike Berry!

Sorting cute girls using IComparable won’t get you a date

Although I found this article on C# sorting algorithms very useful, I think I found one flaw:

[Rolvin] has seen alot of girls around the area, met and chatted with some of them, got their numbers but he never thought about courting or asking some for a date up until now. Rolvin is smart.. he decided to pullout a tissue paper and listed all the names of the girls he met and some basic information about them. There are 3 things that he thought were important. First, the girl should have a name. Second, the girl that he will down on his list should have an age. And lastly, the “cuteness factor”. He thinks that he is a very handsome guy and he deserves somebody equal or greater than his looks(talk about ego;)).

Ok, now this is our chance to help Rolvin. We need to create the Girl class first.

It was all going so well until the last sentence. I think Rolvin probably needs to give in now.

Using PHP to Output RFC3339 Dates from MySQL for Atom Feeds

Creating an Atom feed manually in PHP is fairly easy – it is just like generating HTML. However the Atom specification is quite strict on the date format required:

A Date construct is an element whose content MUST conform to the “date-time” production in [RFC3339]. In addition, an uppercase “T” character MUST be used to separate date and time, and an uppercase “Z” character MUST be present in the absence of a numeric time zone offset.

Unfortunately this is very different to the default date format that MySQL exports, so you need to convert it. Thankfully this is very easy. Assuming $line contains your MySQL record array then this code will work:

echo date('Y-m-d\TH:i:s\Z', strtotime($line["date_added"]));

This will output the date in the format required to pass Atom feed validation.

The only other awkward task when exporting an Atom feed is making sure that you send the correct Content-type declaration in the header. The default header Content-type for PHP output is text/html. For an Atom feed this should be application/atom+xml instead. To do this, include the following line at the top of your code, before you have output anything to the client:

header('Content-type: application/atom+xml');

Your feed should now return the correct content type, and contain dates that conform to the Atom specification.

Weekend Photography

I was visiting a friend this weekend, and he has the most beautifully photogenic child:

She was fascinated by the camera too, so made a great model. There’s more on my flickr account.

JavaScript: Creating a Smooth Auto-Hiding Toolbar

When displaying photographs or other multimedia, a toolbar is a great way to manage the navigation – its simple, intuitive and unintrusive. It’s even less likely to detract from the experience if it hides itself automatically when not in use, and it looks cool if it does this in a slick, smooth way. For a simple example, see my Street Photography page.

Although you can do this quite easily in Flash, I prefer to work in JavaScript as it gives you much more control over search engine behaviour, and you can use the same components for users without JavaScript enabled – you don’t need two versions of your site. The following scripts work for all of the main browsers – IE, Firefox, Safari and Chrome.

The first stage is to make sure that you turn the scrollbars off on the page – the interface for displaying your photos is going to be all on one screen, with no need for the user to scroll up and down. So in your main CSS file:

body {
	overflow: hidden;
}

Now in your HTML you want to define the DIV that will make up the toolbar. This can be anywhere in your HTML code:

	<div id="topbar">
	</div>

In your CSS file, position this block as you would like it for users without JavaScript enabled:

div#topbar {
	position: absolute;
	left: 0px;
	top: 0px;
	background-color: #CCCCCC;
	background-image: url('/images/topback.png');
	background-repeat: repeat-x;
	width: 100%;
	height: 34px;
}

Notice that I’m giving it an absolute position of 0px x 0px – so top left. I’m also describing its width as 100% – all the way across the screen, and its height as a set 34px. I’m giving it a background, which is simply a PNG with a basic gradient.

Now create a text file called nav.js – this is going to be the JavaScript file that controls the showing and hiding of the top navigation bar.

var mode="none";
var toppos = 0;

function getMouse(ev) {

	var ypos = 0;
	var xpos = 0;

	if (!ev) {
		ypos = window.event.clientY;
		xpos = window.event.clientX;
	} else {
		ypos = ev.clientY;
		xpos = ev.clientX;
	}

	if (ypos<100 && toppos<0 && mode!="show") {
		mode="show";
		process();
	}
	if (ypos>100 && toppos>-30 && mode!="hide") {
		mode="hide";
		process();
	}

}

function process() {

	if (mode=="hide") {

		if (toppos>-30) {
			toppos = toppos - 1;
			document.getElementById("topbar").style.top = toppos + "px";
		} else {
			mode="none";
		}

	} else if (mode=="show") {

		if (toppos<0) {
			toppos = toppos + 1;
			document.getElementById("topbar").style.top = toppos + "px";
		} else {
			mode="none";
		}

	}

	if (mode!="none") {
		setTimeout("process()",20);
	}

}

To break this down a little:

  • The first two variables are called mode and toppos. mode defines what should be happening right now - whether the toolbar should be retracting into the top of the screen (hide) or dropping down into the frame (show). toppos gives the current position of the toolbar.
  • The getMouse(ev) function (which we'll come to later) gets the current x and y position of the mouse within the browser window. If the mouse is under 100 pixels from the top of the window then we'll start dropping the toolbar down. If it is over 100 pixels then we'll start hiding the toolbar.
  • The process()> function is a self-repeating function that actually manages the movement in a smooth way. It calls itself every 20 miliseconds while there is work to do, and increments the toolbar by 1px either upwards or downwards, depending on the current mode. When the toolbar is fully hidden or fully shown, it changes the mode to "none" and stops calling itself.

We now need to call this nav.js file from your HTML file. So between the </head> and <body> tags put the following script declaration:

<script type="text/javascript" src="nav.js"></script>

Finally all you need to do is call the getMouse(ev) function from the HTML file. So in the HTML file change your <body> tag to something like this:

<body onMouseMove="getMouse(event);">

This will cause getMouse to be called everytime the mouse moves within the browser window, along with position information, allowing it to determine whether the toolbar should be shown or hidden.

You should now find that you have a nice toolbar box that moves in and out of the top of your page. The next stage is to start filling that with content and buttons (just put them with in the DIV). If you ensure that you use SEO-friendly JavaScript function calls then you should have a nifty-looking JavaScript powered site that is completely compatible with SEO best practice and users without JavaScript.

Changing the location of the iTunes Music library XML files

In iTunes it’s very easy to change the location of your music folders – simply change the “iTunes Music folder location” option in Preferences:

Changing iTunes music folder location

However this only tells iTunes where your music is stored – it does not tell iTunes where to put your iTunes Music Library.xml file. This file and its associated itl files store extra information about your music library – such as your ratings, play counts etc. This information is almost as vital as the music itself, but unfortunately cannot be moved from your Windows My Music folder.

To work around this you need to move the location of your My Music folder. To do this (assuming you’re using XP), close iTunes and then go to Start -> Run and type “regedit”, then press Enter.

Navigate to the following section in the Registry Editor:

HKEY_CURRENT_USER
-> Software
   -> Microsoft
      -> Windows
         -> Current Version
            -> Explorer
               -> User Shell Folders

You’ll see in the right Window a list of folders such as “AppData”, “Cache”, “Favourites” etc. The Data column will tell you where these folders are located on your hard drive. Have a look and see if you have an entry for “My Music”. If you do, simply right click on it, select Modify and enter a new path to where you want the “My Music” folder to be.

Changing the location of My Music

If you do not have a My Music folder then go to Edit > New > Expandable String Value. Enter “My Music” as the name of this value, and then right click on it, select Modify and enter the path as above.

You should end up with something like this:

Modified Registry result

iTunes will now look for its XML file in [the path you've entered]\iTunes\, so its import that you copy your existing iTunes folder to the new location before starting iTunes.

SEO Friendly JavaScript URLs

This is a really simple topic, but something so many developers get wrong. Lets imagine you have a page showing photographs. When you click on the next button, you want some nice friendly JavaScript to take the user to the next photo. You develop a function to do this called “showNextPicture()” and put this on your Next button:

<a href="javascript:showNextPicture()" title="Show Next Photo">Next Photo</a>

The problem here is that users without JavaScript (and search engines) cannot follow the link to the next photo. Instead, a link like this works so much better:

<a href="link-to-next-photo.php" onClick="showNextPicture(); return false;" title="Show Next Photo">Next Photo</a>

In this case when the user has JavaScript enabled then their browser does the following when clicking on that link:

  • See’s the onClick event, runs the showNextPicture() function.
  • See’s return false, which tells it not to follow the href

If the user has JavaScript disabled (or is a search engine) then it does the following when clicking on that link:

  • It doesn’t understand onClick, so it ignores the NextPicture() function
  • Instead it just directly follows the href link

All users get a great user experience, and you end up with your pages properly indexed in the search engines.

Gaming Google Adwords the Experian Way

There has been a lot of talk in the SEO community recently about the hypocrisy of Google’s aparent 2-tier model when it comes to link building – if you’re a brand then its good PR, if you’re a small business then its spam. However its great to see a big brand that is truly rolling with Google’s developing attitude. If you were a small site would you get away with this?

These ads look alarmingly similar:

Experian Adwords Ads

And they go to strangely similar looking URLs:

Experian Adwords Ads

Experian Adwords Ads

But of course the pages are completely different brands. That’s ok then:

Credit Expert Home Page

Experian Home Page

Great user experience!


←Older