Skip to content

Instantly share code, notes, and snippets.

@vshih
Created April 27, 2009 06:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vshih/102363 to your computer and use it in GitHub Desktop.
Save vshih/102363 to your computer and use it in GitHub Desktop.
Ubiquity bugmenot.com - Queries bugmenot.com and posts login information for the current page.
/*
bugmenot.js
Queries bugmenot.com for the current page, populates login information and submits.
Written by Victor Shih (vshih at yahoo.com, http://blog.vicshih.com/2009/04/bugmenot-command-for-ubiquity.html)
Initial idea and some code from Onur Yalazı (onur@yalazi.org, http://www.yalazi.org/ubiquity) and Brandon Goldsworthy.
*/
const MIN_RATE_PERCENT = 50; // only show entries that rate 50% or more
CmdUtils.CreateCommand({
name: 'bugmenot',
icon: 'http://www.bugmenot.com/favicon.gif',
homepage: 'http://blog.vicshih.com/2009/04/bugmenot-command-for-ubiquity.html',
author: {name: 'Victor Shih', email: 'vshih at yahoo.com'},
license: 'MPL',
description: 'Queries bugmenot.com for the current page, populates login information and submits.',
help: 'Enter the desired index of the bugmenot.com entry; defaults to top entry.',
takes: {'entry number': /\d*/},
preview: function(pblock, entryNum) {
var url = this._getUrl();
pblock.innerHTML = 'Passwords for ' + url + ':<br />';
this._showEntries(pblock, url, entryNum.text);
},
execute: function(entryNum) {
var url = this._getUrl();
var entryID = parseInt(entryNum.text) - 1;
if (isNaN(entryID)) entryID = 0;
var proxy = this;
this._getEntries(url, function(entries) {
if (entries.length == 0) {
displayMessage('Bugmenot.com - no entries found.');
return;
}
if (entryID >= entries.length) entryID = entries.length - 1;
proxy._submit(entries[entryID]);
});
},
// Private members
_entries: {},
_decode: function(data, key) {
var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var o11 = '', o21 = '', o31 = '';
var h11 = '', h21 = '', h31 = '', h41 = '';
var bits1 = '', i1 = 0, enc1 = '';
do {
h11 = b64.indexOf(data.charAt(i1++));
h21 = b64.indexOf(data.charAt(i1++));
h31 = b64.indexOf(data.charAt(i1++));
h41 = b64.indexOf(data.charAt(i1++));
bits1 = h11 << 18 | h21 << 12 | h31 << 6 | h41;
o11 = bits1 >> 16 & 255;
o21 = bits1 >> 8 & 255;
o31 = bits1 & 255;
if (h31 == 64) {
enc1 += String.fromCharCode(o11);
}
else if (h41 == 64) {
enc1 += String.fromCharCode(o11, o21);
}
else {
enc1 += String.fromCharCode(o11, o21, o31);
}
}
while (i1 < data.length);
var strInput = enc1;
var strOutput = '';
var intOffset = (key + 112) / 12;
for (i1 = 4; i1 < strInput.length; ++i1) {
var thisLetter = strInput.charAt(i1);
var thisCharCode = strInput.charCodeAt(i1);
var newCharCode = thisCharCode - intOffset;
strOutput += String.fromCharCode(newCharCode);
}
return strOutput;
},
_getUrl: function() {
var url = Application.activeWindow.activeTab.document.location.toString();
var i = url.indexOf('://');
if (i != -1) url = url.substr(i + 3);
var i = url.indexOf('/');
if (i != -1) url = url.substr(0, i);
return url;
},
_getEntries: function(url, callback) {
if (this._entries[url]) {
callback.call(this, this._entries[url]);
}
else {
var proxy = this;
jQuery.ajax({
url: 'http://www.bugmenot.com/view/' + url,
success: function(html) {
var key = parseInt(html.match(/key.=.(-?[0-9]*)/)[1]);
var ps = html.split('<div class="account"');
var result = [];
for (var i = 0; i < ps.length; ++i) {
var pair = ps[i].match(/d\('(.*)'\)/g);
if (!pair) continue;
var rate = parseInt(ps[i].match(/[0-9]{1,3}%/));
if (rate < MIN_RATE_PERCENT) continue;
var username = proxy._decode(pair[0].match(/'(.*)'/)[1], key);
var password = proxy._decode(pair[1].match(/'(.*)'/)[1], key);
result.push({username: username, password: password, rate: rate});
}
proxy._entries[url] = result;
callback.call(proxy, result);
},
error: function() {
// The ajax call seems to fail when there are no bugmenot entries found.
// In this case, none of the parameters are informative, so just callback with no entries
callback.call(proxy, []);
}
});
}
},
_showEntries: function(pblock, url, entryID) {
var proxy = this;
this._getEntries(url, function(entries) {
if (entries.length == 0) {
pblock.innerHTML += 'No entries found.';
return;
}
for (var i = 0; i < entries.length; ++i) {
proxy._showEntry(pblock, i, entries[i], entryID);
}
});
},
_showEntry: function(pblock, i, entry, entryID) {
var index = (i + 1).toString();
var style = (entryID == index) ? 'style="background-color: green"' : '';
pblock.innerHTML += '<div ' + style + '>' + index + (index.length == 1 ? '&nbsp;' : '') + ' ' + entry.username +
' <span style="color: gray">' + entry.password + '</span> ' + entry.rate + '%</div>';
},
_submit: function(entry) {
var ins = jQuery(CmdUtils.getDocument()).find(':text,:password');
var pass = ins.filter(':password:eq(0)');
ins.slice(0, ins.index(pass)).filter(':text:last').val(entry.username);
pass.val(entry.password)[0].form.submit();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment