Using Micro Summaries of Firefox

When geeks can be useful too

Karine recently decided that she wanted a laptop. I cannot remember why, but she also decided that a MacBook would be definitively cool. So we went to town and had a look at the hardware. Karine took the time to search for benchmarks and tests to be comforted in her choice. We started to track eBay and Apple Refurb. In the end, she realized that the Refurb offered the warranties that she was looking for, with an interesting price saving.

Once the choice was made, began the time of the Apple Store Page Refresh Syndrom. The drama occured the day she was having a break, and then the one-click susbscription refused to work before all the nice MacBook had found new happy owners.

So, what are you doing when you're a geek and a nice girl is crying for her own Apple laptop ? Yes, you find a way to monitor the Apple Store so as to be the first to be ready to buy next time.

Remember your greatest quality is laziness

There are many ways to monitor a page and to be notified when it is updated. The easiest solution is to rely on what you can find. Remember: never reinvent the wheel (or only if it's fun).

We first tried to find a plugin for Firefox that would show up a notification when a page is updated and we installed Notify. But the plugin was sending far too false positive notifications (and actually, it continues to do so while I'm writing this). I don't pretend it does not work, but it didn't the job we wanted out of the box, so we tried to find something else.

I could have written some Python script to crawl the Refurb for us and provide us some summary of the available laptops. The most difficult part of this solution would have been to handle the notification: Karine was mainly using MS Windows both at work and at home, and I didn't want to search for a graphical solution on this platform. The notification could have been sent by mail, but I didn't enjoy this solution at the moment, thinking it was too slow for our need (I am not sure I have the same opinion today).

Then Karine found a short description about the Live Titles, or Micro Summaries of Firefox. After some search, I found out that this was in fact a way to define a dynamic bookmark label. I first found some samples and later some documentation to start with. I decided that I wanted to know more about it.

You could say (will you ?) that this kind of notification is a very shy one, and we have to check frequently the Firefox window to see it some good news happened. And you would be right. But please consider that for someone using a lot its computer and the web browser, it's more interesting to have a quick glance at a label on the windows than to have to refresh a page from a somewhat loaded server. And that was what scratched my itch at this very moment, nothing else.

Time to write some code

Micro Summaries... What's this ?

Micro Summaries simply consist of one XSL stylesheet which will be associated to all bookmarked pages matching a given pattern. When you bookmark a page whose URL matches a Micro Summary definition, the Add Bookmark dialog provides you a combo box to define the title instead of a text field, thus giving you the choice to set a static label or to use the existing dynamic one.

This page introduces the Firefox Micro Summaries, but this one is far more interesting when it comes to the moment you have to write your own.

At first, I was worried by the fact that all the provided samples were very simple. They were often composed of one or two labels and some values easely extracted from the bookmarked page. Then I realized that they were XSLT documents after all, and that I probably could use all the power of XSL transformations to build the label I wanted.

Let's dive in it

First, Micro Summaries are XML documents, and they make use of XML namespaces. It is very important to know about namespaces because a Micro Summary document contains at least tags from two distinct ones: microsummaries, and XSL of course.

A Micro Summary definition needs very few information. The root tag is <generator>, from the microsummaries namespace, and has a name attribute. The root tag has at least two children.

<?xml version="1.0" encoding="UTF-8"?>
<generator xmlns="http://www.mozilla.org/microsummaries/0.1" name="Applestore">
  <template>
    <transform xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <!-- All XSLT code goes here -->
    </transform>
  </template>
  <pages>
    <include>http://store\.apple\.com/Apple/WebObjects/francestore\.woa/.*</include>
  </pages>
  <update interval="5" />
</generator>

Note the additional <update> tag which specifies that the Summary will have to be refreshed every five minutes. The update involves retrieving the data from the website of course. You will find some other tags in documentation which I confess I didn't try to study. All I needed was there.

Now, the AppleStore application

What I tried to retrieve first was some value to determine if MacBook laptops were available. This could be done by searching the lines announcing the refurbed products and looking for the one displaying MacBook. So, I sit down and managed to remember the syntax of XPath expressions to produce something like this:

	/html/body//form/table[@id='rep']/tbody/tr/td/b

Which gave me the following result.

Note that the XPath expressions given here rely on the french refurb pages. They shall be adapted to get something operational in other languages.

Of course, in the end, I would have kept only the text and get rid of pictures (but it was cool to display this for the screenshot, and it helps to understand what I have extracted from the page).

From there I thought I only had to search the lines where I could find the string MacBook. But I realized that I needed to differentiate MacBook and MacBook Pro. And I didn't know how to write some condition with these inputs to distinguish both of them.

So I tried to gather another source of information in the page. Meanwhile, I also decided to not only detect if MacBook laptops were available but also to count how many there were. Finally, I wrote the following expression.

	/html/body//form/table[@id='rep']/tbody/tr/td/span/b[contains(normalize-space(.), 'Refurb')]

And this time, I got:

From these strings, all I had to do was to select the ones related to MacBooks and to count them. To extract these lines, I chose to use the White and Black words, which only appeared in lines concerning MacBooks.

To make sure the method was correct, I also decided to count the lines related to MacBook Pro, and then even the ones for iMacs. In these cases, I simply had to search for MacBook Pro and iMac terms on the lines.

Counting the lines is a bit tricky because XLST does not provide lvalues. There is no way to define anything else than constants. So computing values can be achieved using recursivity only. In the following template, nodes is the list of gathered strings, item is the pattern we are looking for. The inner variable count is used to carry the temporary value of the result count through iterative calls.

<template name="count">
	<param name="nodes" />
	<param name="item" />
	
	<choose>
	  <when test="$nodes">
	    <variable name="node" select="$nodes[1]" />
	    <variable name="count">
	      <call-template name="count">
		<with-param name="nodes" select="$nodes[position() != 1]" />
		<with-param name="item" select="$item" />
	      </call-template>
	    </variable>
	    <choose>
	      <when test="contains($node, $item)">
		<value-of select="$count + 1" />
	      </when>
	      <otherwise>
		<value-of select="$count" />
	      </otherwise>
	    </choose>
	  </when>
	  <otherwise>0</otherwise>
	</choose>
      </template>

Building the label

Counting lines containing a given item is only a matter of calling the previous template with the list of lines and the wanted pattern. The result of the call gives the count value. Here is an excerpt of the code showing how is displayed the count of white MacBook laptops. Note the <text> element to display some text around the value computed.

	<text>MacBooks: </text>
	<variable name="count-macbooks-w">
	  <call-template name="count">
	    <with-param name="nodes" select="$entries" />
	    <with-param name="item" select="string('White')" />
	  </call-template>
	</variable>
	<value-of select="$count-macbooks-w" />
	<text>w </text>

Registering the Micro Summary

If no micro summary is registered in your browser, or if the <pages> directives do not match the page you are currently watching, then trying to bookmark will raise the following dialog.

Micro Summaries can be registered using a simple script. Its main job will be to check that the browser can register the sheet, and then a simple line will suffice.

<script>
  const warning = "Sorry, you need a microsummary-enabled browser like Firefox 2.0";
  function addGenerator(url) {
    if (typeof window.sidebar == "object" &&
      typeof window.sidebar.addMicrosummaryGenerator == "function")
      window.sidebar.addMicrosummaryGenerator(url);
    else
      alert(warning);
  }
</script>
<button onclick="addGenerator('http://10.165.16.164/applestore.xml')">
  Install the Apple Store MacBook microsummary!</button>}

Again, there is more than one way to do this. But remember it was only a quick hack to monitor the Apple Store and a nice way have an overview of the technology.

Now, if you used the previous script, and are trying to bookmark an Apple Store page, then your Add Bookmark dialog is updated so that you can choose the live title instead of typing a static one. Hey Karine, there are laptops available!

The complete Micro Summary, code for the Apple Store can be downloaded here. Note that the short script I used to register it needs its complete location.

Waiting for kisses

As said before, Micro Summaries are a very tiny way to notify something to the user. If the content of the title is rather important, the best use is probably to store it on your personal toolbar.

To conclude, I shall add that I discovered quite recently that Micro Summaries were stored in your Firefox profile under the microsummary-generators directory (I am using Firefox under Debian to do this). It is very easy to remove a generator simply by deleting the XML file stored there.

For the record, a week later the Apple Store offered many refurbed laptops and Karine bought its MacBook. And after that, she still tells I'm staying too much in front of my computer!

Modifié le 29/04/2007 et généré par Achille 2.0 le Friday 01 June 2007 20:19