Anyway, once that was out of the way, it works pretty well. The only thing to know is that in order to see the notification when your reputation changes, you have to click the down arrow at the top of the Google sidebar, select "Configure Gadgets" and enable notifications for this specific gadget. If you want to try it out and don't want to know how it works, click here to download. The site for the code is here.
<------------Code Discussion ------------------------------>
I tried out the gadget designer for this code. I was pretty impressed with how easy it was to put something usable together. Also, the build/debug cycle was very fast. The editor was a little lacking though, and I really missed the powerful editor from Eclipse. As you can see below, very little code was needed for this gadget due to the powerful API, along with the fairly simple project requirements. There is a little more involved, such as layout and options handling, but this is almost all of the code that the gadget uses.
/**
This file is part of SOReptracker.
Foobar is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SOReptracker is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SOReptracker. If not, see <http://www.gnu.org/licenses/>.
Main javascript file
Handles retrieving a users reputation and periodically updating it
Adam Cabler
*/
var myRep = -1;
var defaultUpdateTime = 5;
var newUpTime;
var timeUntilUpdate = 0;
var defTxt = "Enter your ID and Press Enter to Check Reputation";
var timeout;
/*
Called when the view is opened
Used to init some values and start the clock
*/
function view_onOpen() {
repLabel.size = 12;
repLabel.innerText = defTxt;
newUpTime = options.getValue("uptime");
if (newUpTime == "") {
newUpTime = 5;
}
clock();
}
/*
Used to handle the heartbeat signal
Once the rep is filled the first time,
It gets the rep once on every timeout
*/
function clock() {
debug.info("Checking");
if (myRep != -1) {
if (timeUntilUpdate <= 0) {
timeUntilUpdate = newUpTime * 60; //in minutes
getUserRepPage();
}
timeUntilUpdate -= 5;
}
view.setTimeout(clock, 5000);
}
/*
Handles updating the timeout
*/
function updateIntChanged(newValue) {
newUpTime = newValue;
timeUntilUpdate = 0;
}
/*
Gets the page from the server
Because of some weird caching, I had to use
the random addition to the url. Not sure
what I would I have done if the site didn't accept this
*/
function getUserRepPage() {
var params = {};
var url = "http://stackoverflow.com/users/" + userID.value;
url += '?cache_buster_xyz=' + Math.random();
var request = new XMLHttpRequest();
request.onreadystatechange = response;
try {
debug.info("sending request for : " + url);
request.open('GET', url, false);
request.send();
} catch(e) {
debug.warn('Could not retrieve rep for id: ' + e.message);
}
function response() {
if (request.readyState != 4) {
return;
}
if (request.status == 200) {
parseRep(request.responseText);
request = null;
}
}
}
/*
Parses the servers response. since the site didn't
return "valid" xml, I had to search it the old-fashioned way
instead of using the built-in dom parser
*/
function parseRep(docText) {
var lines = docText.split("<a href");
for (var i = 0; i < lines.length; i++) {
if (lines[i].indexOf(userID.value) != -1 && lines[i].indexOf("reputation score") != -1) {
var repTag = "reputation score\">";
var start = lines[i].indexOf(repTag)
var end = lines[i].indexOf("<", start);
myRep = lines[i].substring(start + repTag.length, end);
showRep(myRep);
break;
}
}
}
/*
Shows the response from the server
*/
function showRep(newRep) {
var nI = parseInt(newRep);
var oI = parseInt(repLabel.innerText);
repLabel.size = 40;
repLabel.innerText = newRep;
if (nI != oI && !isNaN(oI)) showNotifier(nI, oI);
}
/*
Triggers the notifier functionality
*/
function showNotifier(nI, oI) {
var item = new ContentItem();
if (nI > oI) {
item.heading = "You Gained Rep!";
} else if (nI < oI) {
item.heading = "You Lost Rep!";
} else { //can't get here - used for testing
item.heading = "Nevermind";
}
item.snippet = "Your reputation is now: " + nI;
plugin.AddContentItem(item, gddItemDisplayAsNotification);
}
/*
When enter is pused on the edit box (code 13 == Enter),
the page is fetched and parsed
*/
function userID_onkeypress() {
if (event.keyCode == 13) getUserRepPage();
}
/*
Updates the hyperlink when it is clicked
*/
function a1_onclick() {
if (repLabel.innerText != defTxt) {
a1.href = "http://www.stackoverflow.com/users/" + userID.value;
}
else {
a1.href = "http://www.stackoverflow.com/";
}
}
/*
Updates the timer option
*/
function optionChanged() {
updateIntChanged(options.getValue("uptime"));
}