By Mark Blomsma
December 14, 2007
The World Wide Web is becoming more and more a resource for video. Online newspapers are receiving competition from television stations when it comes to getting your attention online. If your computer is running Windows Vista, then the obvious way to keep informed about what's happening in the world is by running a Vista gadget that searches the Internet for new content. Of course, building a search engine inside a gadget is a little ambitious, but integrating a Vista gadget with Truveo Video Search is definitely within the realm of possibility. With the NFL competition in full swing, let's take a look behind the scenes of the making of an NFL Video of the Day gadget for Windows Vista.
The Gadget
Let’s have a look at the gadget first. What you want to build is a gadget that randomly displays a recently published NFL video. You'd like it to sit in your Windows Vista Sidebar so that when you feel like it, you can look at the screen, see a small thumbnail, and decide whether to watch the video. When you move your mouse over the thumbnail you want a tooltip to tell you what the video is about—a description. This is what the gadget will look like:
You can download the gadget here.
Truveo RSS API
AOL's Truveo offers an extensive array of APIs. You can use XML, Ruby, Flash, or Asynchronous JavaScript and XML (AJAX) to execute queries and embed search results in your own application. But for this gadget, I explored a different way to embed search results in my application. Instead of using the AJAX API, I decided to explore the possibilities of using an RSS feed to retrieve search results.
The search for the feed I needed went as follows. I visited the Truveo site and chose the sports section. The search box automatically was filled with the text
category:"Sports." Next, I chose the NFL.com channel. Now the search was extended to
category:"Sports" channel:"NFL.com." Because I was interested only in recent videos, I chose to sort the search results by "Most Recent." This selection updated the search to
category:"Sports" channel:"NFL.com" sort:mostRecent. The page offers a unique RSS feed, which displays the results of this query; clicking the RSS feed icon ( ) shows the feed and the URL needed to access the feed. In this case, the feed URL is http://xml.truveo.com/rss?query=category%3A%22Sports%22%20channel%3A%22NFL.com
%22%20sort%3AmostRecent. As you can see from the URL, the query is passed as a parameter to the RSS generator.
Opening the URL will display the feed in your browser. When you look at the source code, you can see the underlying XML. For your application, you're interested only in the search items. With a little copying and pasting, you can extract the format of a single item:
<item xmlns:media="http://search.yahoo.com/mrss"> <title>Week 11: Vince Young highlights</title> <link>http://xml.truveo.com/rd?i=1828017150&a=rss&p=2</link> <guid>http://xml.truveo.com/rd?i=1828017150&a=rss&p=2</guid> <description><img src="http://thumbnail.search.aolcdn.com/truveo/images/
thumbnails/6D/C5/6DC54186D81E95.jpg"><br>Highlights of Vince Young in
the Titans 34-20 loss to the Broncos.</description> <pubDate>Tue, 20 Nov 2007 02:26:27 -0500</pubDate> <source url="http://www.nfl.com">NFL.com</source> <media:content url="http://xml.truveo.com/rd?i=1828017150&a=rss&p=2" duration="143"
lang="en-US" medium="video" /> <media:credit role="author">NFL Films</media:credit> <media:copyright>© 2007 NFL Enterprises LLC</media:copyright> <media:category>Sports</media:category> <media:keywords>Tennessee Titans, Denver Broncos, Vince Young</media:keywords> <media:thumbnail url="http://thumbnail.search.aolcdn.com/truveo/images/thumbnails/6D
/C5/6DC54186D81E95.jpg"/> </item>
Building the Gadget
Developers use HTML and JavaScript to build gadgets in Windows Vista. When you run HTML in the Vista Sidebar, you have some extra objects and events to interact with the Sidebar environment. If you’re unfamiliar with gadgets for Windows Vista, my previous article, “Xdrive as Data Storage Device for Windows Vista Gadgets,” might be useful.
Let’s start with the basic HTML:
<body onload="Page_onLoad();"> <g:background> <img id="imgNFLlogo" src="NFL-corner.png" /> <div id="divLink"></div> <div id="divStatus"></div> </g:background> </body>
This will be the HTML shown in the Sidebar. It's fairly empty, right? Don’t worry--you'll create all the magic by using Cascading Style Sheets (CSS) and JavaScript. As shown, the onload event of the body triggers a method called Page_onLoad(). You're using one of the "extra" objects available in gadgets <g:background>; this will make your background transparent.
Tip Debugging JavaScript can be tedious and complicated. While developing this gadget, I used Microsoft Visual Studio 2008 Beta 2 to debug my JavaScript. Using this new debugger helps quite a bit during development, but the debugger won’t work after you deploy the gadget. To help with the debugging, I’ve created the divStatus element. This element won’t be visible when the gadget is complete, but I make it visible during development and debugging.
The Page_onLoad() method looks like this:
// Eventhandler, will fire when the body of our gadget has completed loading.
function Page_onLoad()
{
// Enable next line when gadget is complete
// divStatus.style.display = "none";
UpdateGadget();
}
function UpdateGadget()
{
var url = 'http://xml.truveo.com/rss?query=category:"Sports"%20channel:
"NFL.com%20sort:mostRecent"';
request = new XMLHttpRequest();
request.onreadystatechange = request_onReadyStateChange;
request.open("GET", url);
request.send();
window.setTimeout(UpdateGadget, (1000 * 60 * 60 ));
}
The Page_onload() calls UpdateGadget(), which, as you can see, creates an XMLHttpRequest and accesses the URL you created (or should I say discovered?) in the previous paragraph. Because you want your gadget to be responsive and not block your Sidebar thread, you'll use an asynchronous call to request the data. The method to be called when the state of our request changes is request_onReadyStateChange().
Notice in the preceding code that you end by calling window.setTimeout(UpdateGadget, (1000 * 60 * 60 )). This call will start a timer and cause the UpdateGadget code to be called again in an hour (yes, it’s called the Video of the Day, but really you get a new video each hour).
// Convert the status of the request object to a description.
function getStatusDescription(status)
{
var description;
switch(status)
{
case 0:
description = "Uninitialized";
break;
case 1:
description = "Open";
break;
case 2:
description = "Sent";
break;
case 3:
description = "Receiving";
break;
case 4:
description = "Loaded";
break;
default:
description = "Error";
}
return description;
}
// Eventhandler, will be fired for every state change on our XMLHttpRequest.
function request_onReadyStateChange()
{
var status = request.readyState;
divStatus.innerText = getStatusDescription( status );
if ( status == 4 )
{
showItemOfTheDay();
}
}
The event handler logs the status of the request to your status area. When the status equals 4, the request is loaded; this is when you want to show your item.
// Generate a random number where the number will be maxed by the 'max' parameter.
function getRandomNumber( max )
{
var random = Math.floor(Math.random()*max);
return random;
}
function showItemOfTheDay()
{
var xmlDocument = request.responseXML;
var nodes = xmlDocument.selectNodes( '//item' );
var numberOfItems = nodes.length;
var randomNumber = getRandomNumber( numberOfItems );
var selectedNode = nodes[randomNumber];
var thumbnail = selectedNode.selectSingleNode( 'media:thumbnail//@url' );
var title = selectedNode.selectSingleNode( 'title' );
var link = selectedNode.selectSingleNode( 'link' );
divLink.innerHTML = '<a href="' + link.text + '" target="_blank"><img src="'
+ thumbnail.text + '" width="90" height="60" alt="' + title.text +
'" border="0"/></a>';
}
The showItemOfTheDay() method extracts the XML from the request and then selects all the items in the feed. Next, you generate a random number and select the appropriate item in the array of nodes. Last but not least, you extract the necessary elements and attributes and build an image link that will open the video in a new browser window and show you the video.
Note Proper positioning of the HTML elements is accomplished by using the following CSS:
body
{
background-repeat: no-repeat;
width: 130px;
height: 120px;
}
#divStatus
{
color: White;
position: absolute;
top: 95px;
left: 10px
}
#divLink
{
position: absolute;
top: 35px;
left: 10px
}
#imgNFLlogo
{
position: absolute;
top: 0px;
left: 80px
}
Packaging the Gadget
All of the code shown so far has been placed in a single HTML file. To create your gadget, you need to create a gadget manifest, which is an XML file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<gadget>
<name>NFL Video of the Day</name>
<namespace>DevelopOne.Windows.Vista.Gadgets</namespace>
<version>1.0.0.0</version>
<author name="Mark Blomsma, Develop-One.">
<info url="http://www.develop-one.com" />
<logo src="logo.png" />
</author>
<copyright>© 2007, Develop-One</copyright>
<!-- The description displays in the Gadget Tile window when the Gadget is selected -->
<description>This gadget will display a random new NFL video every hour.</description>
<icons>
<icon height="48" width="48" src="icon.png" />
</icons>
<hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="Main.htm" />
<permissions>Full</permissions>
<platform minPlatformVersion="1.0" />
</host>
</hosts>
</gadget>
Save this file as gadget.xml. Next, create a .zip file of the HTML, gadget manifest, and the images. Then, change the file extension from .zip to .gadget, and you're ready to deploy your gadget. Just double-click and have fun.
Wrap-Up
In this article, you explored a powerful way to interact with Truveo Video Search: RSS feeds. Then, you used JavaScript and HTML to consume the feed and randomly select a video from the feed. Packaging the Windows Vista gadget is no more complex than creating an XML file and zipping all content.
Although consuming the RSS feed is easy to implement, you also lose something. If you used a Truveo API instead of the RSS feed, you'd have the ability to monitor the use of our application through the My API Account page, a nice benefit of using a Truveo API.
Downloads
Download the gadget here.
Download the source as a .zip file here.

nice!
great post Mark, thanks a lot!