Using Firefox Micro-Summaries
Published:
What are you doing when you’re a geek and a nice girl is crying for her own refurbed Apple laptop ? Yes, you find a way to monitor the Store so as to be the first to be ready to buy next time.
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.
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 into 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.
transform
holds the XSL sheet. The XSL namespace must be present here.pages
provides one or moreinclude
tags, each one holding a regular expression that will be used to match a page URL for which the micro summary can be used.
An 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.
::XML
<?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>
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.
Caution: 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.
::XML
<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.
::XML
<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.
::HTML
<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 store and a nice way have an overview of the technology.
Now, if you used the previous script, and are trying to bookmark a 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 her MacBook. And after that, she still tells I’m staying too much in front of my computer!