Sunday, November 16, 2008

Use Greasemonkey to link UK postcodes to Google Maps

See my last blog post for general details about using Greasemonkey. This titbit of source code uses a large standard regex to match any UK postcode in a web page text (you could be matching paragraph elements) and converts it into a hyperlink to a google map of that area. It assumes that this titbit is inside a script that searches relevant elements of the page and tests them as variable "thisElement".

// Convert postcodes to google map links (z=15 puts names on tube stations)
thisElement.innerHTML=thisElement.innerHTML.replace(/([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)/,"<a href='http://maps.google.com/maps?f=q&hl=en&geocode=&q=$1&ie=UTF8&z=15&iwloc=addr' target=_blank>$1</a>");

Friday, November 14, 2008

Write your own Greasemonkey script to highlight and hide items on a website

Here are some handy code segments that have taken me a little while to work out. Greasemonkey is a useful Firefox plugin with a massive shared library of scripts to do interesting things like adding collapsible folders to your online gmail web page. You can also write your own javascript code for Greasemonkey to apply to web sites you name.

The following code I use for a mystery shopping website I visit regularly but their table of possible assignments available in London can be several pages long. This script helps filter and colour in the table with my preferences (for example out of 80 London assignments I currently have 7 highlighted as suitable).

// ==UserScript==
// @name Website filter
// @namespace Filters
// @include http://mywebsite.com

/* Here I'm searching out items in a table that have been
highlighted in bold already. I'm then searching the bold
text and if it contains "William", I then hide the row
completely. I then go on to pick out items with "London"
in the text in dark green */


var allElements, thisElement;
allElements = document.evaluate(
'//tr/td/b',
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
for (var i = 0; i < allElements.snapshotLength; i++) {
thisElement = allElements.snapshotItem(i);
// Hide these rows
if(thisElement.innerHTML.search(/William/i)>=0) {
thisElement.parentNode.parentNode.style.display="none";
}
// Highlight these elements
if(thisElement.innerHTML.search(/London/i)>=0) {
thisElement.style.color="darkgreen";
}
}

/* In this section I'm searching for any table cell and
checking the text for certain postcodes and addresses.
If there is a match, the cell is highlighted in bold
blue text. */


allElements = document.evaluate(
'//td',
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
for (var i = 0; i < allElements.snapshotLength; i++) {
thisElement = allElements.snapshotItem(i);
// Highlight these addresses
if(thisElement.innerHTML.search(/SE(22|15|1\s)|London Bridge/i)>0) {
with(thisElement.style){
color="blue";
fontWeight="bold";
}
}
}

// ==/UserScript==

Explanations

Regular expressions (Regex) can be a bit cryptic but as you'll need to tailor these in the above code I though I'd explain what these bits do:
search(/William/i) ==> Search anywhere in the string for "William" and return the starting position within the string, the 'i' means that it will not be case sensitive.
search(/SE(22|15|1\s)|London Bridge/i) ==> Search anywhere in the string for "SE22", "SE15", "SE1 " or "London Bridge", ignore case and return the position.

You will also note that the first search that hides matching rows uses parentNode twice on the assumption that the bold text will be in a cell which will be in a row, so the second parent node is the "TR" tag containing the row. By changing the style.display attribute this dynamically hides the row from view (to reset and show the row again you would set style.display to null). Phew.

Useful links

Greasemonkey: https://addons.mozilla.org
XPath syntax: http://www.w3schools.com/XPath

Monday, November 10, 2008

iMacro script to swap between Flickr albums

The following handy iMacro script logs you from one Flickr account to another. I currently have six of these, one for each separate free Flickr album/account I have on the go (there's a maximum of 200 photos you can share for free in each account). All you have to do is install the iMacro plugin into your browser and save the following script not forgetting to add your login and password in the "User set variables" section.

Obviously if Flickr change their main site layout then this may break the script and it would have to be tweaked.

Script Starts

' Last Edit: 13 Nov 2008

' User set variables
' !VAR1 = your login ID, !VAR2 = your password

SET !VAR1 yourlogin@yahoo.com
SET !VAR2 password

' This script is intended to toggle you out of your
' current Flickr account and into one set by the
' variables above so you can easily swap between
' several albums

' Assumptions
' - A Sign Out link is on every Flickr page
' - You are currently logged into Flickr

' Main script

TAB T=1
FILTER TYPE=IMAGES STATUS=ON
SET !ERRORIGNORE YES
TAG POS=1 TYPE=A ATTR=TXT:Sign<SP>Out
TAG POS=1 TYPE=A ATTR=TXT:Sign<SP>in*
WAIT SECONDS=2
TAG POS=1 TYPE=A ATTR=TXT:Sign<SP>in<SP>as<SP>a*
SET !ERRORIGNORE NO
WAIT SECONDS=2
TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:login_form ATTR=NAME:login CONTENT={{!VAR1}}
SET !ENCRYPTION NO
TAG POS=1 TYPE=INPUT:PASSWORD ATTR=ID:passwd CONTENT={{!VAR2}}
TAG POS=1 TYPE=INPUT:SUBMIT ATTR=VALUE:Sign<SP>In
FILTER TYPE=IMAGES STATUS=OFF
URL GOTO=http://www.flickr.com/activity
TAG POS=1 TYPE=SELECT FORM=* ATTR=ID:act-since CONTENT=%lastlogin


Script Ends

Latest changes:
  1. I added the 2 second wait times as Sxipper (a password plugin) seemed to be causing 'focus' problems.
  2. ErrorIgnore is used so that the script still works (though slower) if you have logged off but are still on the Flickr site.