Archive by Author

How to access web console from Greasemonkey userscripts

Userscripts are helper Javascript programs that you can add to your browser to automate and optimize the web pages you visit. Greasemonkey is a Firefox extension to run userscripts. The web console is a tool built into Firefox and other browsers that can be helpful during userscript development.

How can you access the web console from Greasemonkey userscripts? First of all, you should not do this in production. However, logging to the web console can be a useful tool during development.

Here’s how you do it:

// Put this at the top of your userscript
var console = unsafeWindow.console;

Bonus: How to access your userscript’s jQuery from the web console

// Expose userscript's jquery to the web console
unsafeWindow.$ = $;

Again, do not do this in production.

Userscript for faster deletion of MediaWiki spam

A couple weeks ago I posted a userscript that makes banning MediaWiki spammers easier by setting good defaults for the user ban form. Since then, I’ve had to ban a lot of spammers, so I thought I should remove another point of friction.

For some reason, MediaWiki chooses to not provide direct deletion links on the User Contributions page, so after banning a spammer you have to click through to each piece of spam before deleting it. This may have been an acceptable user experience in Web 1.0 days, but it’s a ridiculous set of hoops to jump through today.

My goal is to eventually make banning a spammer and deleting all the spam they’ve posted a one-click process. If there’s an existing solution for this, I’d love to hear about it.

Since I needed to do some DOM manipulation, I chose to use jQuery in the userscript. This was also a lot easier than I might have expected. Userscripts really are a very solid technology.

// ==UserScript==
// @name           Mediawiki - Fast delete on user contributions view
// @namespace      https://userscripts.org/users/457667
// @description    Adds a delete link for every page on the user contributions view
// @include        http://example.com/index.php/Special:Contributions/*
// @require        https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// ==/UserScript==

// Add page delete links to the user contributions page
function enhanceHistory() {
  "use strict";

  // Find the history link for each revision
  $('#bodyContent ul li')
    .find('a[href*="action=history"]')
    .each(function(i) {
      // Append a page delete link after each history link
      var url = this.toString().replace('action=history', 'action=delete');
      $('<span> | </span><a href="' + url + '">del</a>').insertAfter($(this));
  });
}

enhanceHistory();

I passed the above through JSHint to make sure there’s nothing silly in it, but I haven’t consulted the jQuery style guide so it may not conform to the usual formatting.

The page delete links still lead to a standard confirmation form, so this doesn’t violate the RESTful practice of only using links for reading content rather than changing it.

Here’s a screenshot of what it adds to the user interface:

Userscript to make banning MediaWiki spammers easier

Somehow, I’ve come to be responsible for administering two MediaWiki-powered wikis. The main burden is having to ban spammers, which sometimes sign up in batches of 20 at a time.

To help with process, I’ve put together the following browser userscript. On Firefox, you can easily set it up using the Greasemonkey extension. Opera and Chrome have their own facilities.

The script basically makes the default values on the user ban form sane, so I can just click through without fiddling with dropdown and checkboxes. Obviously, the ban has to be permanent. Obviously, I don’t want spammers emailing anyone.

// ==UserScript==
// @name           Blocker
// @namespace      https://userscripts.org/users/457667
// @include        http://example.com/index.php/Special:Block/*
// ==/UserScript==

// Set default expiry to 'infinite' or 'indefinite', depending on MediaWiki version
function makeExpiryInfinite () { "use strict";
  // Get the element
  var elExpiry = document.getElementById('wpBlockExpiry');
  if (!elExpiry) { elExpiry = document.getElementById('mw-input-wpExpiry'); }

  // Abort if element not found
  if (!elExpiry || !elExpiry.children) { return; }

  // Find the infinite option
  var expiryNodes = elExpiry.children;
  var index = 0;
  for (var i in expiryNodes) {
    if (expiryNodes[i].label && expiryNodes[i].label in {infinite:1, indefinite:1}) {
      index = i;
    }
  }

  // Set dropdown to the infinite option
  elExpiry.selectedIndex = index;
}

// Automatically prevent user from sending e-mail
function preventEmail() { "use strict";
  // Find check box
  var elEmailBan = document.getElementById('wpEmailBan');
  if (!elEmailBan) { elEmailBan = document.getElementById('mw-input-wpDisableEmail'); }

  // Abort if it's not there
  if (!elEmailBan) { return; }

  // Check the box
  elEmailBan.checked = true;
}

// Automatically prevent user from sending e-mail
function reallyBanThatIP() { "use strict";
  // Find check box
  var elHardBlock = document.getElementById('mw-input-wpHardBlock');
  if (!elHardBlock) { elHardBlock = document.getElementById('mw-input-wpHardBlock'); }

  // Abort if it's not there
  if (!elHardBlock) { return; }

  // Check the box
  elHardBlock.checked = true;
}

makeExpiryInfinite();
preventEmail();
reallyBanThatIP();

I’ve been hearing wonderful things about userscripts for years, but this is the first one I’ve put together for myself. It’s actually very easy to write these, assuming you know Javascript and have tools like Firefox’s Web Console and the Web Developer extension handy.

I’m planning to enhance it a little so that it handles the slightly different form for banning anonymous users, but I’m not sure if it makes sense to submit to any official repository. It helps with running small wikis that have open memberships, so there isn’t any one site I can identify it with. Obviously, it’s not suited for Wikipedia, as they have a very different set of problems.

Edit: Updated the script with better handling for banning anonymous users by IP address.

Setting up a fresh Windows system

I’m setting up a new primary system and I thought I’d jot down some notes.

Ninite is probably the quickest way to install all the necessary software (Chrome, 7-zip, Dropbox, iTunes, Picasa, etc). You click the checkboxes and it rolls you a custom, hands-off installer. They upsell to an auto-update service, but there are free alternatives like FileHippo Update Checker.

Speaking of Dropbox, it proved a lifesaver. If you aren’t familiar with it, it’s a service that automatically syncs (and backups) a folder between all your machines. My last hard drive failed, but because all my personal files are on Dropbox I didn’t lose any of them. They have a free 2GB account available, and if you join they’ll toss some extra free space my way as well.

I also set up a few Firefox extensions. With extensions, the goal is always is to have as few as possible, as there is a history of extensions slowing down Firefox performance. Here are the ones I chose:

HTTPS Everywhere is of course a great security boon. LastPass is a secure cross-browser way to manage the hundreds of passwords we all have. Xmarks is a bookmarks synchronizer which I prefer over Firefox Sync because it’s cross-browser.

I have a few goals with the new system:

  • Keep the desktop empty of files
  • Keep all personal files in a single location (e.g. \Dropbox)
  • Keep all work files in a single location (e.g. \Projects)

The last one might be the trickiest, as all the different Eclipse-based IDEs I’ll need to install will all try to grab a workplace for themselves.

 

DB2 Express-C 9.7.5 released with Oracle compatibility

My team just put out DB2 Express-C 9.7.5. The big new feature is Oracle compatibility, which is now available in the free edition. It includes PL/SQL, CLPPlus, and other related things.

DB2 Express-C is a free database. It’s fairly straightforward to install on your own machine or deploy on a public cloud like Amazon EC2 or IBM SmartCloud Enterprise. Disclaimer: I’m the guy who puts together the DB2 virtual images for SCE.

DB2 University is a good place to learn how to use DB2 at your own pace.

Materials for the Hadoop workshop at CASCON

This is the syllabus for the workshop I’m chairing at CASCON 2011 with @mariusbutuc and @bsteinfe. If you’re interested, you can also take the course at your own pace online at BigDataUniversity.

SSH

Attendees will be provided with access to machines running Hadoop in a cloud environment. The necessary SSH credentials will be provided in class.

Materials

SQL6048N A communication error occurred during START or STOP DATABASE MANAGER processing

I’ve written about issues related to “SQL6048N A communication error occurred during START or STOP DATABASE MANAGER processing” before, but I thought I’d add a few short notes.

  1. Your machine needs to be able to ping itself. If it can’t ping itself, it can’t DB2 itself either.
  2. The output of hostname, db2set -all, and cat /home/db2inst1/sqllib/db2nodes.cfg needs to match.

If your machine can’t ping itself, cat /etc/hosts. Chances are, you need to add a line like the following:

127.0.0.1 myhostname.mydomain myhostname

If DB2SYSTEM is set to the wrong value, db2set -g DB2SYSTEM=`hostname` will fix it on Linux.

If db2nodes.cfg has the wrong value, overwrite it with the right one.

Chairing a Hadoop workshop at CASCON 2011

I’ll be chairing the Crunching Big Data in the Cloud with Hadoop and BigInsights workshop at CASCON 2011 in Toronto on Wednesday, November 9th. @BSteinfe and @MariusButuc will be joining me as co-chairs.

The workshop will be an all day hands-on introduction to Hadoop, HDFS, MapReduce, Hive, and JAQL. The plan is to have ready Hadoop clusters running in the cloud for the various exercises.

Hadoop is a parallelized data processing framework. It lends itself very nicely to running in cloud environments like Amazon EC2 and IBM SCE, as the core concept is to split sophisticated queries across clusters of commodity hardware. On a basic level it’s an implementation of MapReduce in Java, but a great many tools in its eco system make it easy to formulate and execute queries on the fly.

The material will have some things in common with the free Hadoop Fundamentals course you can take on Big Data University today, though naturally adapted for the CASCON themes and with added hands-on instruction.

Next steps

Run Firefox 5+ and Firefox 3.6 side by side on Windows

(Edit: Corrected instructions so that HTTP links in other apps will still open in Firefox.)

There’s an intranet application that I need to use that does not work in Firefox 4, Firefox 5, Chrome, Opera, or Safari. It also runs painfully slowly in Microsoft Internet Explorer 8. Since it does support Firefox 3.6, I thought I’d try running two different versions of Firefox side by side.

  1. Install Firefox if you don’t have it. At the time of writing, the latest stable version is Firefox 5.
  2. Download Firefox 3.6.
  3. Start the installation and choose the Custom installation type.
  4. Install it to a non-standard location such as “C:\Program Files\Mozilla Firefox 3.6\”
  5. I recommend telling it to not create any shortcuts, as it will otherwise overwrite the Firefox 5 shortcuts.
  6. Open up the folder where you keep your Firefox shortcuts. Make a copy of one of them.
  7. Right-click -> Properties and add -ProfileManager to the target path (not the “Start in” field)
    • "C:\Program Files\Mozilla Firefox\firefox.exe" -ProfileManager
  8. Make sure Firefox is closed and launch that shortcut. It will open up the Firefox Profile Manager.
  9. Create a new profile. Name it something like: Firefox36
  10. Close the Profile Manager.
  11. Configure the main shortcut as follows:
    • Mozilla Firefox
    • "C:\Program Files\Mozilla Firefox\firefox.exe" -P default
    • "C:\Program Files\Mozilla Firefox\"
    • Note: An earlier version of this post added the -no-remote parameter to the command line above. This prevented HTML links in other applications (e.g. Outlook, Lotus Notes) from using this browser. You only need to set it on one of the two shortcuts, and I’ve modified the instructions accordingly with the assumption that this shortcut is to your primary browser.
  12. Configure the other shortcut as follows:
    • Mozilla Firefox 3.6
    • "C:\Program Files\Mozilla Firefox 3.6\firefox.exe" -P Firefox36 -no-remote
    • "C:\Program Files\Mozilla Firefox 3.6\"
  13. Voila!


Links

Example of #BigData: Social Media Counts

Here’s an interesting example from the InfoSphere BigInsights/Hadoop class I’m attending right now. Note that Social, Mobile, Games, and Heritage are tabs that you can switch between.