Sunday 28 March 2010

Attacked ‘b Terminator

So living aboard we’ve a Thetford Loo. These come with cassettes that need emptying, in our case bi-weekly. In the meantime they get fuller and fuller and smellier and smellier so ‘er-in-doors has tried any number of ways of making the boat smell nice, this has ranged from Potpourri to scented candles. So far so smelly... until this week when she got some electronic thing that sets off when it notices movement. A motion sensitive Glade thing or something.

It's not actually all that bad except that the smell just masks the other smells so it's a bit like putting perfume on a turd, that and it sets itself off every time I enter the loo (being motion activated) - sounding like some sort of piston on a mad Steampunk bio-mechanical creation dreamed up by China MiĆ©ville, or on a clunky Terminator (not like the nice one played by Summer Glau). Actually that does sound sort of bad really. It leaves me smelling perfumed turds and terrified… I think that this is one of those things that might find its way into the bin when she’s not watching!

terminatortv

Wednesday 17 March 2010

removeParent

Nah, this isn’t about how your parents mess you up, it’s about JavaScript (or ECMAScript if you prefer). You know how GMail has that groovy thing where you can add a number of email addresses to a contact? There’s this cool bit where you can click on a [add] and another field appears below the email field. Besides the new email field there is a [remove] link which gets rid of it if’n you don’t need it. I spent ages trying to figure out how this was done and discovered that the way to do it is:

onclick="this.parentNode.parentNode.removeChild(this.parentNode);"

How cool is that?

Thursday 11 March 2010

Beards and mapping

In regards to the previous posting about the mapping between Google and Outlook csv files I actually think that Google general approach is to clump First, Middle and Last names into one Name. I think that this is a nicer way to do it TBH but I'm open to argument one way or another...?

I found the following at some god-awful time this morning when I couldn't sleep:

Can't work out where I am yet as I often get too itchy to make it past Sea Captain, actually I'm happy with that!

The Blogger blog Google Data API Tips is tops! As is this discussion forum.

Tuesday 9 March 2010

outlook and google csv files

google outlook
Name,
Given Name,
Additional Name,
Family Name,
Yomi Name,
Given Name Yomi,
Additional Name Yomi,
Family Name Yomi,
Name Prefix,
Name Suffix,
Initials,
Nickname,
Short Name,
Maiden Name,
Birthday,
Gender,
Location,
Billing Information,
Directory Server,
Mileage,
Occupation,
Hobby,
Sensitivity,
Priority,
Subject,
Notes,
Group Membership,
E-mail 1 - Type,
E-mail 1 - Value,
E-mail 2 - Type,
E-mail 2 - Value,
E-mail 3 - Type,
E-mail 3 - Value,
E-mail 4 - Type,
E-mail 4 - Value,
IM 1 - Type,
IM 1 - Service,
IM 1 - Value,
Phone 1 - Type,
Phone 1 - Value,
Phone 2 - Type,
Phone 2 - Value,
Phone 3 - Type,
Phone 3 - Value,
Address 1 - Type,
Address 1 - Formatted,
Address 1 - Street,
Address 1 - City,
Address 1 - PO Box,
Address 1 - Region,
Address 1 - Postal Code,
Address 1 - Country,
Address 1 - Extended Address,
Address 2 - Type,
Address 2 - Formatted,
Address 2 - Street,
Address 2 - City,
Address 2 - PO Box,
Address 2 - Region,
Address 2 - Postal Code,
Address 2 - Country,
Address 2 - Extended Address,
Organization 1 - Type,
Organization 1 - Name,
Organization 1 - Yomi Name,
Organization 1 - Title,
Organization 1 - Department,
Organization 1 - Symbol,
Organization 1 - Location,
Organization 1 - Job Description,
Website 1 - Type,
Website 1 - Value,
Website 2 - Type,
Website 2 - Value
First Name,
Middle Name,
Last Name,
Title,
Suffix,
Initials,
Web Page,
Gender,
Birthday,
Anniversary,
Location,
Language,
Internet Free Busy,
Notes,
E-mail Address,
E-mail 2 Address,
E-mail 3 Address,
Primary Phone,
Home Phone,
Home Phone 2,
Mobile Phone,
Pager,
Home Fax,
Home Address,
Home Street,
Home Street 2,
Home Street 3,
Home Address PO Box,
Home City,
Home State,
Home Postal Code,
Home Country,
Spouse,
Children,
Manager's Name,
Assistant's Name,
Referred By,
Company Main Phone,
Business Phone,
Business Phone 2,
Business Fax,
Assistant's Phone,
Company,
Job Title,
Department,
Office Location,
Organizational ID Number,
Profession,
Account,
Business Address,
Business Street,
Business Street 2,
Business Street 3,
Business Address PO Box,
Business City,
Business State,
Business Postal Code,
Business Country,
Other Phone,
Other Fax,
Other Address,
Other Street,
Other Street 2,
Other Street 3,
Other Address PO Box,
Other City,
Other State,
Other Postal Code,
Other Country,
Callback,
Car Phone,
ISDN,
Radio Phone,
TTY/TDD Phone,
Telex,
User 1,
User 2,
User 3,
User 4,
Keywords,
Mileage,
Hobby,
Billing Information,
Directory Server,
Sensitivity,
Priority,
Private,
Categories

Or:

outlook csv

First Name,
Middle Name,
Last Name,
Title,
Suffix,
Initials,
Web Page,
Gender,
Birthday,
Anniversary,
Location,
Language,
Internet Free Busy,
Notes,
E-mail Address,
E-mail 2 Address,
E-mail 3 Address,
Primary Phone,
Home Phone,
Home Phone 2,
Mobile Phone,
Pager,
Home Fax,
Home Address,
Home Street,
Home Street 2,
Home Street 3,
Home Address PO Box,
Home City,
Home State,
Home Postal Code,
Home Country,
Spouse,
Children,
Manager's Name,
Assistant's Name,
Referred By,
Company Main Phone,
Business Phone,
Business Phone 2,
Business Fax,
Assistant's Phone,
Company,
Job Title,
Department,
Office Location,
Organizational ID Number,
Profession,
Account,
Business Address,
Business Street,
Business Street 2,
Business Street 3,
Business Address PO Box,
Business City,
Business State,
Business Postal Code,
Business Country,
Other Phone,
Other Fax,
Other Address,
Other Street,
Other Street 2,
Other Street 3,
Other Address PO Box,
Other City,
Other State,
Other Postal Code,
Other Country,
Callback,
Car Phone,
ISDN,
Radio Phone,
TTY/TDD Phone,
Telex,
User 1,
User 2,
User 3,
User 4,
Keywords,
Mileage,
Hobby,
Billing Information,
Directory Server,
Sensitivity,
Priority,
Private,
Categories

google csv

Organisation of google.csv file (as of 09/03/2010):

Name,
Given Name,
Additional Name,
Family Name,
Yomi Name,
Given Name Yomi,
Additional Name Yomi,
Family Name Yomi,
Name Prefix,
Name Suffix,
Initials,
Nickname,
Short Name,
Maiden Name,
Birthday,
Gender,
Location,
Billing Information,
Directory Server,
Mileage,
Occupation,
Hobby,
Sensitivity,
Priority,
Subject,
Notes,
Group Membership,
E-mail 1 - Type,
E-mail 1 - Value,
E-mail 2 - Type,
E-mail 2 - Value,
E-mail 3 - Type,
E-mail 3 - Value,
E-mail 4 - Type,
E-mail 4 - Value,
IM 1 - Type,
IM 1 - Service,
IM 1 - Value,
Phone 1 - Type,
Phone 1 - Value,
Phone 2 - Type,
Phone 2 - Value,
Phone 3 - Type,
Phone 3 - Value,
Address 1 - Type,
Address 1 - Formatted,
Address 1 - Street,
Address 1 - City,
Address 1 - PO Box,
Address 1 - Region,
Address 1 - Postal Code,
Address 1 - Country,
Address 1 - Extended Address,
Address 2 - Type,
Address 2 - Formatted,
Address 2 - Street,
Address 2 - City,
Address 2 - PO Box,
Address 2 - Region,
Address 2 - Postal Code,
Address 2 - Country,
Address 2 - Extended Address,
Organization 1 - Type,
Organization 1 - Name,
Organization 1 - Yomi Name,
Organization 1 - Title,
Organization 1 - Department,
Organization 1 - Symbol,
Organization 1 - Location,
Organization 1 - Job Description,
Website 1 - Type,
Website 1 - Value,
Website 2 - Type,
Website 2 - Value

In case you were wondering (I surely was) what "Yomi" meant: It's not a name but a reading of the name.

I originally did a search for it and found that it was something to do with the underworld and got all excited that my friends were in the mafia or something!

array_combine

This nigh on killed me except I solved it last night while I was asleep. Now to turn it into a loop!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>CSV12</title>
    </head>
    <body>
        <?php
          // file names.csv:
          /*
Name,Email Address,Phone Number
Bob Smith,bob@smith.com,01234567890
Martha Jones,martha@jones.com,0987643210
Joe Bloggs,joe.bloggs@gmail.com,01484522869
           */
          // get the file into an array
          $file = "names.csv";
          $fileHandle = fopen("names.csv", "r");
          // check that the array is a csv file
          if (substr(strrchr($file, '.'), 1) == "csv") {
            // count the number of lines in the file
            $lines = count(file($file));
            // display the result of the count
            echo "<p>There are $lines lines in $file</p>";
            // if there are more than 2 continue
            if ($lines > 1){
              // this is the first line as an array, we'll be using this as the
              // key to our key value array
              $firstLine = fgetcsv($fileHandle);
              // print the 1st line
              print_r($firstLine);
              // this is the second line, we'll be using this as the value to
              // out key value array
              $secondLine = fgetcsv($fileHandle);
              // print the 2nd line
              print_r($secondLine);
              // use array_combine to use values from the 1st line as keys and
              // values form out 2nd line as values to out key value array
              $firstSecond = array_combine($firstLine, $secondLine);
              // print it all out nice to check
              print_r($firstSecond);
              /*
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>CSV12</title>
    </head>
    <body>
        <p>There are 4 lines in names.csv</p>Array
(
    [0] => Name
    [1] => Email Address
    [2] => Phone Number
)
Array
(
    [0] => Bob Smith
    [1] => bob@smith.com
    [2] => 01234567890
)
Array
(
    [Name] => Bob Smith
    [Email Address] => bob@smith.com
    [Phone Number] => 01234567890
)
    </body>
</html>            
                */
            }
            // if less than 2 it's not a valid file
            else {
              echo "There are not enough lines to work with.";
            }
          }
        ?>
    </body>
</html>

Friday 5 March 2010

To test for MIME or to not test for MIME

So I was looking to check if a file to be uploaded is of the type csv and I thought that I'd be able to check the MIME type of the file. Nothing is ever that easy though. The experiments I made pointed to the MIME being of the type application/vnd.ms-excel, upon further reading though I discovered that actually the MIME type could be text/tab-separated-values or (the preferred choice, it would seem) text/csv.

So I could use lots of nice logical ORs or just sack the whole thing of looking at MIME types and just check the extension of the file using substr(strrchr($fileName, '.'), 1), thanks PHP MySQL Tutorial.

Thursday 4 March 2010

PHP and SCV files

PHP has a lovely function which reads a line of a .csv file into an array called fgetcsv.

Given a .csv file like this:

Line One, 001, £11
Line Two, 002, £22
Line Three, 003, £33
Line Four, 004, £44
Line Five, 005, £55

We can iterate through the .csv file using this php code:

<?php
  // Open a file for reading.
  $file_handle = fopen("test.csv", "r");
  // Start the table html.
  echo '<table cellspacing="2" cellpadding="2" border="1">';
  // Work through each line of the file
  while (!feof($file_handle) ) {
    // Get each line and convert it into an array
    $line_of_text = fgetcsv($file_handle, 1024);
    // Use each array as the contents for the line of the table
    print("<tr>");
    print("<td>".htmlentities($line_of_text[0])."</td>");
    print("<td>".htmlentities($line_of_text[1])."</td>");
    print("<td>".htmlentities($line_of_text[2])."</td>");
    print("</tr>");
  }
  // End the table html
  echo "</table>";
  // Close the file.
  fclose($file_handle);
?>

But if we don't know how many records are in each line then we can use:

<?php
  $file_handle = fopen("test.csv", "r");
  echo '<table cellspacing="2" cellpadding="2" border="1">';
  while (!feof($file_handle) ) {
    $line_of_text = fgetcsv($file_handle, 1024);
    print("<tr>");
    foreach ($line_of_text as $cell) {
      print("<td>".htmlentities($cell)."</td>");
    }
    print("</tr>");
  }
  echo "</table>";
  fclose($file_handle);
?>

Which is much nicer. But does sometimes mess up so you could check that the returned line is actually an array before processing it as it'll fall over if there are dodgy carriage returns and such like. So:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
  </head>
  <body>
    <?php
      $file_handle = fopen("test.csv", "r");
      echo '<table cellspacing="1" cellpadding="1" border="1">';
      while (!feof($file_handle) ) {
        $line_of_text = fgetcsv($file_handle, 1024);
        if(is_array($line_of_text)){
          print("<tr>");
          foreach ($line_of_text as $cell) {
            print("<td>".htmlentities($cell)."</td>");
          }
          print("</tr>");
        }
      }
      echo "</table>";
      fclose($file_handle);
    ?>
  </body>
</html>

Which'll give us

Line One 001 £11
Line Two 002 £22
Line Three 003 £33
Line Four 004 £44
Line Five 005 £55

Wednesday 3 March 2010

PHP and Google Base API

So in order to learn about PHP and the Google Data API you need to know about the basic concepts of Google Base; in order to know about the basic concepts of Google Base you need to know about the Google Data API.

Cool, basically the Google Data API is all about HTTP requests and XML. XML is lovely and I know it, perhaps biblically ;-). HTTP requests I know less well but basically seem to me to be either GET or POST (GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT are all valid HTTP Request Methods (http://www.w3.org/Protocols/rfc2616/rfc2616.html)), but GET AND POST seem to me a lot like the Java thing of having setters and getters in order to access data within an object indirectly.

The following 3 things all do the same thing:

  1. http://www.google.com/base/feeds/snippets?bq=digital+camera%5Bitem%20type:products%5D%5Bprice%20%3C%20150%20USD%5D&max-results=10&orderby=modification_time
  2. http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera%5Bprice%20%3C%20150%20USD%5D&max-results=10&orderby=modification_time
  3. <?php
      require_once 'Zend/Loader.php';  // this should point to your Zend lib installation
      Zend_Loader::loadClass('Zend_Gdata_Gbase');
    
      $service = new Zend_Gdata_Gbase();
    
      $query = $service->newSnippetQuery();
      $query->setCategory('products');
      $query->setBq('digital cameras[price < 150 USD]');
      $query->setMaxResults('10');
      $query->setOrderBy('modification_time');
    
      $feed = $service->getGbaseSnippetFeed($query);
    
      // Print our results
      foreach ($feed->entries as $entry) {
        echo '<p><b>' . $entry->title->text . '</b><br/>';
        echo '<small>' . $entry->id->text . '</small><br/>';
        echo $entry->content->text . "</p>";
      }
    ?>

If we break down the URIs above we get:

  1. http://www.google.com/base/feeds/snippets?bq=digital+camera%5Bitem%20type:products%5D%5Bprice%20%3C%20150%20USD%5D&max-results=10&orderby=modification_time
    which, once run through php's urldecode gets you:
    http://www.google.com/base/feeds/snippets
    ?bq=digital camera[item type:products][price < 150 USD]
    &max-results=10
    &orderby=modification_time
  2. http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera%5Bprice%20%3C%20150%20USD%5D&max-results=10&orderby=modification_time
    which, once run through php's urldecode gets you:
    http://www.google.com/base/feeds/snippets/-/products
    ?bq=digital camera[price < 150 USD]
    &max-results=10
    &orderby=modification_time

Which both match the php code above nicely.

Monday 1 March 2010

The Elephant's Child via Opera Speak

Pretty self-explanatory TBH, I was playing with Opera Speak and wanted to use it to play audio of stuff that I was interested in, then I thought of recording the output to listen to later, then I realised I couldn't record using the machine I was using without buying a loopback audio cable, so I bought one off of Ebay and I created this MP3.

Then, to play it back I used some code from Digital Inspiration to embed a Google Reader player and the result is below.

I love the Six Honest Serving Men poem as it offers a really nice way of formulating a problem. Particularly good in terms of programming.

Like tears in the rain...

Such a cool video via The Brothers Brick

Blade Runner - Tears in Rain (in LEGO) from Zach Macias on Vimeo.

The M255 tutorial on Saturday was a blast, especially as I knew nearly all the stuff being discussed, guess that's just as well seeing as I've done it before. It's just that last time I wasn't at all impressed with the language, nor the approach if I'm honest. I don't know why, perhaps it was because I'd just looked at PHP and databases and was so very impressed with the power that they represented that OOP just seemed so crass?

I also got chided that I was using the wrong language, I use Object Orientated Programming where as it should be Object Oriented Programming, go figure, I never knew I was using foreign slang!

Spent Saturday night at Fakenham and went to the Cinema there on Sunday afternoon to watch Youth In Revolt which was top. I'm sure that I have laughed more in a film, but not often. Well worth a look if you have the opportunity.