Category: Uncategorized

Using the Grid plugin in Compiz

Recently I’ve been introduced to the Grid plugin in Compiz – this is a fantastic little plugin that snaps your windows to predefined positions on the screen. After using it for the last couple of weeks I can’t imagine going back to not using it.

To get access to it you will need to install the compiz settings manager, and load Compiz’s “Fusion Plugins Extra”:

sudo apt-get install \
    compizconfig-settings-manager \
    compiz-fusion-plugins-extra

Once you’ve done this simply enable it:

  1. System, Preferences, CompizConfig Settings Manager
  2. In the Filter box in the top left, type in “grid”
  3. Tick the box to enable it and click “Close” (bottom left)

Now try using Ctrl-Alt and numbers on your keypad. CA-9 will snap a window into the top right corner (press it a few more times to get different sizes) and CA-8 will make it snap to the top half of the screen (the number is the position on the screen, you’ll get the gist of it).

Check out this demo video:

Happy Ubuntuing!

Cc and Bcc field size in Gmail

The Cc and Bcc field sizes in Gmail are too small to work with if you’re sending to more than about 20 email addresses. The following bookmarklet will increase their height when used:

javascript:(function(){var%20e=window.frames[3].document.getElementsByTagName('textarea');%20for(i=0;i<e.length;i++){%20if(e[i].name=='cc'%20of%20e[i].name=='bcc')%20{%20e[i].style.height='150px';%20}%20};})();

To install (in Firefox).

  1. Right click on your Bookmarks toolbar and choose “New Bookmark”
  2. Enter a name for the Bookmark, e.g. “Big Cc Field”
  3. Into the location, paste the above code
  4. Save the bookmark

Now when at Gmail and you can see the Cc or Bcc fields you can click the new Bookmark link to make them bigger.

To find out more about Bookmarklets, check out the Bookmarklet page on Wikipedia.

Mosgiel Centenary Celebrations – 1985.

I recalled an event I participated in back in 1985 which was the Mosgiel 100 year centenary parade. As a pupil of one of the local primary schools (Reid Park Primary) we were primed with dress of the era and a song that was nowhere near as bad as some radio jingles. We got to ride on a float down the main street, oh what joy!

“I’m a hundred year old kid – don’t you see,
I’m proud to see the end of our first century.
From 1885 through ’til 1985,
We’ll still be century children at our next centenary.”

Author unknown, can you help?

Walk To Work Day

Today was Walk To Work Day in Dunedin, an initiative spearheaded by Living Streets Aotearoa with the support of Sport Otago and the DCC. I decided to make the trip as the amount of excercise I get thanks to the extreme convenience of my scotter is minimal. I left home at 7:20 this morning and arrived in the Octagon at about 8:30 where a few stands were laid out for registration. The registration process was rewarded with a $7 voucher redeemable at Barakah, MASH, The Ra Bar, Alibi or The Craic. I chose MASH and a nice looking breakfast bap which was delicious, but unfortunately my order was forgotten in the rush of breakfast time cafe operations. After a reminder it turned up with an apology.

They say New Zealand is a small place and indeed it is – I ran into community advocates Frank Buddingh and Nina Arron from Lawrence who were on the registration stands. A familiar face was very much a welcome sight. I first ran into Frank and Nina some time ago when Frank was looking for an alternative provider for the Buddingtree Consultancy website.

For me the nicest thing (other than the fantastic weather!) about walking into town was it was a chance for me to “sit down” and listen to some podcasts. Listening to Leo Laporte, Jono Bacon and Randal Schwartz interview Jamie Cameron about Webmin on the FLOSS weekly podcast was a delight, especially as in my dark days I had a fair use for Webmin, so much so that I bought Jamie’s “Using Webmin” book.

Now that I have my walking method sussed all I need to do is load up my iPod and get an early night and a good sleep beforehand – unfortunately the early night and good sleep was thwarted last night by some jQuery and AJAX goodness and also by Zoe night-babbling, then Linus who woke up crying because “Ada ate my pie in a dream!” and then some more Zoe babbling. Things had quietened down by about 4am anyway.

Check out the local Channel Nine TV coverage at http://www.ch9.co.nz/node/14223

Installing MagentoCommerce – problems

MagentoCommerce

MagentoCommerce is an open-source enterprise level ecommerce system suitable for high end ecommerce websites. We’re in the throes of developing a large solution for a local company, and the developers involved in provisioning the site are installing local copies of Magento on their Apache servers to test with.

Here’s a list of issues that I’ve come across with installing Magento, and how I’ve solved them. For the record I’m using Magento 1.3.2.2 (released 19.07.2009)

1. Can’t get past the second install step

This is the step that asks you for your database password. If the database you’re specifying doesn’t exist then you can’t proceed. I’m sure there’s a bug here because it’s like an error message isn’t displayed. Would love to dig into this but our project is on a tight time frame. MAKE SURE YOU CREATE THE DATABASE YOURSELF FIRST (no tables required).

2. Can’t log in after installation

If after logging in you go to the /admin directory and you can’t log in, it’s probably because of the URL that you used to install it. I tried installing it to http://localhost/, http://127.0.0.1/ and http://192.168.2.10/ (my IP) all with the same result. After googling it seemed to be something to do with Magento refusing to set a cookie for a top-level domain (or somesuch). Workarounds are to use a host name that has a dot in it, e.g. http://localhost.localdomain/ (or in my case, http://bob-desktop.local). Add this to your hosts file, you may have to restart your browser for it to pick it up.

3. Firefox keeps asking you to download a PHTML file.

After doing a completely fresh install of Apache2, PHP5, mysql, Magento etc on a fresh machine (Ubuntu 9.04, Firefox 3.0.11) Firefox kept asking me what I wanted to do with the PHTML file when accessing the freshly untarred Magento directory. It took me ages to find an answer to this, but it was as simple as clearing your cache in Firefox. I dicked around with the Apache configuration, permissions, .htaccess files etc and finally found a comment about the Firefox cache.

4. AllowOverride All

Magento uses a .htaccess file in the root directory. I noticed that the default for /var/www is AllowOverride None which prevents Apache from looking at the content of .htaccess files. While this didn’t cause me trouble, I did set it to “AllowOverride All” while trying to solve #3. The file is /etc/apache2/sites-enabled/000-default, line 11. Note there may be security implications of doing this if you’re the administrator of a shared hosting environment and as such you should read about the AllowOverride directive.

Installation requirements:

From a stock Ubuntu 9.04 machine I had to install the following packages to support Magento:

  • libapache2-mod-php5
  • php5-curl
  • php5-mcrypt
  • php5-mysql
  • php5-gd
  • mysql-server

Also, I have this command on standby to reset the Magento environment back to scratch (deletes the magento directory, drops the database, untars the source file and creates the empty database again)

cd /var/www ; rm -Rf magento ; tar xvfz /home/bob/magento-1.3.2.2.tar.gz ;
   chmod -R a+rw magento ; mysqladmin -uroot -proot -f drop magento ;
   mysqladmin -uroot -proot create magento

That’s all for now.

Screen scraping with jQuery

jQuery logoDuring the course of my job I often find myself faced with the task of migrating information from an existing website to our own content management system.  In the past my approach to this task has been to assess the source code of the existing site and see whether it’s feasible to use a combination of curl, regular expressions and string manipulation.  Sometimes this is straightforward but increasingly this method is becoming less and less viable as it’s too intensive.

I’ve been using jQuery a lot recently and it occurred to me that I could use jQuery’s selectors to target the information that I’m interested in a web page, and then using Ajax POST it to my own script that would be ready waiting to then do something useful with the data, e.g. validate it and save it in a database.  For educational purposes I was keen to keep this completely client-side if possible (except for a script to receive the information).  See later on for a server-side solution.

The situation I was up against was a page that had a heap of data in a table (about 90 items), but the table was interspersed with random images to split it up and make it more pleasing to the eye.  Fortunately for me, all of the data that I wanted was neatly wrapped in <div class=”information”></div> tags.  Selecting these div tags with jQuery is really easy by using $(‘div.information’).

My first problem was that in order to use jQuery, the web page you’re looking at has to be using it.  Fortunately there’s a quick bookmarklet called jQuerify that allows you to load jQuery onto any web page.  Once you’ve got that then you can write further bookmarklets of your own to do stuff.

So, my evil evil plan was to combine a jQuery selector, jQuery’s each() construct, and jQuery’s ajax support to post the content of each div to a “scraper” script, like so:

$('div.information').each(function(){
  $.post('http://localhost/scraper.php',{
    data: this.innerHTML
  });
});

I loaded my source page, clicked the jQuerify bookmarklet and then pasted the code above into the Firebug console (what, oh you’ll need that…) and it was flawless … except that the browser security model stepped in and prevented the ajax call because the XHTTPRequest object is not allowed to post information from one domain to another.  I was stuck – I googled around for a while looking for workarounds, and investigated the use of JSONP but the transport method seemed more weighted at retrieving information rather than posting it.

So, I was stuck with a simple question: “How can I get information from one site to another by using the browser?” – the simplest answer to this question is of course to have a form on the source website, that when submitted posts to the target.  Thanks to the power of JavaScript, modifying the DOM of a loaded web page is a doddle.  Therefore it should be simple to create a form on the page after it has loaded (client side, remember), create and populate some form fields with data and then submit the form to my scraper script.

Suddenly my intentions had outgrown a bookmarklet, but I would still need one for jQuerify and one for my “Scraper Utils”.  My new bookmarket simply asked jQuery to load a local JavaScript file in exactly the same was that jQuery was loaded in the first place:

javascript:$.getScript('http://localhost/scraper.js');

Now I had the freedom of writing chunk loads of stuff in my local scraper.js file.

Scraper = {};
Scraper.createForm = function()
{
  var form = document.createElement('form');
  form.setAttribute('method', 'POST');
  form.setAttribute('action', 'http://localhost/scraper.php');
  document.getElementsByTagName('body')[0].appendChild(form);
  return form;
}
 
Scraper.createSubmitButton = function()
{
  var button = document.createElement('input');
  button.setAttribute('type', 'submit');
  return button;
}
 
Scraper.createFormField = function(name)
{
  var field = document.createElement('textarea');
  field.setAttribute('name', name);
  field.setAttribute('rows', 10);
  field.setAttribute('cols', 50);
  return field;
}		
 
var ScraperForm = Scraper.createForm();
$('div.information').each(function(){
  var field = ScraperForm.appendChild(Scraper.createFormField('data[]'));
  field.value = this.innerHTML;
});
// Create a field that we can post with:
ScraperForm.appendChild(Scraper.createSubmitButton());

You can see here that I’ve set up a few functions, createForm(), createFormField(), createSubmitButton() and then at the bottom I wrap them all together with the $(‘div.information’).each(…) construct.  The end result of this is that when I click my bookmarklet that includes the scraper.js script, a form is created at the bottom of the page and a textarea for each div.information is created that holds the innerHTML from that div.

Then, by clicking the Submit button, the browser posts all of that information across to http://localhost/scraper.php where I then collect the information from $_POST['data'] and poke it into a database.

It’s pretty rough and ready but could easily be extended to do other things like allow you to specify the selector and target URL for the post when you click the Scraper bookmarket.

Server Side Solution

On my travels I also came across the “PHP Simple HTML DOM Parser” which claims a similar ability like so:

// Create DOM from URL or file
$html = file_get_html('http://www.google.com/');
 
// Find all images
foreach($html->find('img') as $element)
       echo $element->src . '<br/>';
 
// Find all links
foreach($html->find('a') as $element)
       echo $element->href . '<br/>';

You can get a hold of this from Sourceforge at the PHP Simple HTML DOM Parser website.

WordPress Themes