topical media & game development
mashup-flickr-12-Exercise-1-QueryTechnorati.user.js / js
// ==UserScript==
// @name Query Technorati
// @namespace http://www.dopiaza.org/flickr/greasemonkey/
// @description Query Technorati from Flickr photo pages
// @include http://www.flickr.com/photos/*
// @include http://flickr.com/photos/*
// ==/UserScript==
// *** Edit this ***
// You need to put your Technorati API key here
var technoratiAPIKey = 'YOUR-TECHNORATI-API-KEY';
var photoPagePattern = /^(.*\/photos\/[\w@-]+\/\d+\/)/;
// Check that we really are on a photo page
function checkPhotoPage()
{
var isPhotoPage = false;
if (photoPagePattern.exec(window.location.href))
{
isPhotoPage = true;
}
return isPhotoPage;
}
// Normalize the URL, removing any unneeded elements
function normalizeUrl()
{
var url = window.location.href;
var result = photoPagePattern.exec(url);
if (result != null)
{
url = result[1];
}
return url;
}
// Add the "View blogs" link after the privacy element
function addLink(privacy)
{
var parent = privacy.parentNode;
var blogContainer = document.createElement('p');
var blogLink = document.createElement('a');
blogLink.setAttribute('href', '#');
blogLink.setAttribute('class', 'Plain');
var text = document.createTextNode('View blogs');
blogLink.appendChild(text);
styleElement(blogContainer);
blogContainer.appendChild(blogLink);
parent.insertBefore(blogContainer, privacy.nextSibling);
blogLink.addEventListener("click", function(evt)
{
var waiting = document.createElement('span');
waiting.appendChild(document.createTextNode('Waiting for Technorati...'));
blogContainer.replaceChild(waiting, blogLink);
showBlogs(blogContainer, waiting);
evt.preventDefault();
}, true);
}
// Retrieve the list of blogs and display them
function showBlogs(blogContainer, message)
{
var url = 'http://api.technorati.com/cosmos';
var params = 'key=' + technoratiAPIKey + '&url=' + normalizeUrl() + '&limit=100';
GM_xmlhttpRequest(
{
method: "GET",
url: url + "?" + params,
headers:
{
"User-Agent": "Flickr-Technorati-Query"
},
onload: function(response)
{
blogContainer.removeChild(message);
var parser = new unsafeWindow.DOMParser();
var dom = parser.parseFromString(response.responseText, "application/xml");
var errors = dom.getElementsByTagName('error');
if (errors.length > 0)
{
var p = document.createElement('p');
p.appendChild(document.createTextNode('Error: ' + errors[0].firstChild.nodeValue));
styleElement(p);
blogContainer.appendChild(p);
}
else
{
var items = dom.getElementsByTagName('item');
var filteredItems = filterItems(items);
if (filteredItems.length > 0)
{
var list = document.createElement('ul');
for (var i = 0; i < filteredItems.length; i++)
{
addBlog(list, filteredItems[i]);
}
blogContainer.appendChild(list);
}
else
{
var p = document.createElement('p');
p.appendChild(document.createTextNode('No blogs found'));
styleElement(p);
blogContainer.appendChild(p);
}
}
addTechnoratiCredit(blogContainer);
},
onerror: function(response)
{
var p = document.createElement('p');
p.appendChild(document.createTextNode('There was an error retrieving blog information'));
styleElement(p);
blogContainer.appendChild(p);
}
});
}
// Filter out the items we want to display
function filterItems(items)
{
var filteredItems = new Array();
for (var i = 0; i < items.length; i++)
{
var processed = false;
var itemName = items[i].getElementsByTagName('name')[0].firstChild.nodeValue;
// Do we have this blog name in the list yet?
for (var j = 0; j < filteredItems.length; j++)
{
var filteredItemName = filteredItems[j].getElementsByTagName('name')[0].firstChild.nodeValue;
if (itemName == filteredItemName)
{
// We have a match. Let's compare the URLs
var itemUrl = items[i].getElementsByTagName('nearestpermalink')[0].firstChild.nodeValue;
var filteredItemUrl = filteredItems[j].getElementsByTagName('nearestpermalink')[0].firstChild.nodeValue;
// We'll assume here that the longest URL is the most specific
if (itemUrl.length > filteredItemUrl.length)
{
// The new item has a longer URL, so replace the old one.
filteredItems[j] = items[i];
}
processed = true;
break;
}
}
if (!processed)
{
// We haven't encountered this one before, so append it to the list
filteredItems.push(items[i]);
}
}
return filteredItems;
}
// Add this blog to the list
function addBlog(list, blog)
{
var name = blog.getElementsByTagName('name')[0];
var url = blog.getElementsByTagName('nearestpermalink')[0];
var excerpt = blog.getElementsByTagName('excerpt')[0];
var li = document.createElement('li');
li.setAttribute('class', 'Stats');
var a = document.createElement('a');
a.setAttribute('href', url.firstChild.nodeValue);
a.setAttribute('class', 'Plain');
a.appendChild(document.createTextNode(name.firstChild.nodeValue));
li.appendChild(a);
li.appendChild(document.createElement('br'));
li.appendChild(document.createTextNode(excerpt.firstChild.nodeValue));
list.appendChild(li);
}
// Add a credit line, linking back to Technorati
function addTechnoratiCredit(blogContainer)
{
var a = document.createElement('a');
a.setAttribute('href', 'http://www.technorati.com/');
a.setAttribute('class', 'Plain');
a.appendChild(document.createTextNode('Technorati'));
var p = document.createElement('p');
p.appendChild(document.createTextNode('Search results by '));
p.appendChild(a);
styleElement(p);
blogContainer.appendChild(p);
}
//Style a given node so that it matched the side bar
function styleElement(node)
{
node.style.color = '#999999';
node.style.fontSize = '11px';
node.style.lineHeight = '15px';
}
// The script itself starts here
if (checkPhotoPage())
{
var privacyElements = document.evaluate(
"//*[@class='Privacy']",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
if (privacyElements.snapshotLength > 0)
{
addLink(privacyElements.snapshotItem(0));
}
}
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.