Archive for September, 2008

Happy: Hadoop with Python (Jython)

0

The Freebase folks have open sourced their Python (Jython) based Hadoop framework, calling it Happy. Looks interesting, will need to give it a whirl when I get a chance.

Best Way To Automatically Convert Flickr Images to FaceBook Albums?

1

Here’s a lazyweb question for you: what’s the best way to convert my flickr photo stream into facebook albums on an automated, continual basis? I much prefer dealing with flickr than facebook for photos, but many of my lazy friends are on facebook, keep asking for photos, but are apparently unable to click over to flickr or subscribe to the RSS feed.

There should be an easy way to have my photos automagically show up in facebook, right? I tried the top 2 flickr apps in facebook but they don’t seem to do this.

I’m A PC And I Sell Fish

0

As you may know those Apple ads annoy the crap out of me. And I actually like the new Windows ad:

And just to stay with my general Apple disdain, do you have any idea just how closed and crappy the iPhone development process is?

How exactly did the linux crowd turn into Apple fanboys? 

Productivity Tip: Forget The Power Cord

0

How’s this for a productivity tip: leave your power cord at home. I’m in this situation now, and I’ll tell ya, it does bring a razor sharp focus to what you need to be doing with those precious few minutes you have of computer time.

(Of course if I was being really productive I’d be working instead of posting this)

Disco: Erlang/Python Based Map-Reduce

1

Disco is a map-reduce framework written in Erlang and Python. Seems reasonable – I definitely prefer Python to Java for writing maps and reduces, and Erlang is rumored to be good at parallel stuff.

Interestingly no mention of an underlying distributed file system.

Via High Scalability.

Live Maps Rocks

3

Live doesn’t get a lot of love and with those new ads Microsoft needs some serious help getting the word out, so let me say something nice about them. I’ve been using Live Maps lately, mainly because of the “Bird’s eye view”, and it’s quickly becoming my favourite map app. If you have’t tried it give it a shot: http://maps.live.com/ . I’m guessing you’ll like it.

ReaderScroll: Google Reader Style Image Navigation With J-K Keys Bookmarklet

7

Shortly after posting ScrollMonkey I realized the same functionality could be implemented as a bookmarklet, obviating the need for GreaseMonkey, making it available to a lot more people. So here it is implemented as a bookmarklet.

To refresh your memory, the script does a very simple thing – it brings the next image to the top of the browser window so you can see it. You hit “j” to see the following image and “k” to go back to the previous.

To install, click and drag the ReaderScroll bookmarklet to your FireFox toolbar or right click on it if you’re using IE.

Once installed in your toolbar, you can enable it for any website you’re visiting by clicking on it in your toolbar. For example, go to any of these pages with lots of images and then click the bookmarklet. Then click anywhere on the page you’re viewing and hit the “j” key several times until the first large image is at the top of the browser window. Now you can navigate to the next image by hitting “j” again and go back to previous images with “k”.

The bookmarklet doesn’t have the disadvantages associated with the ScrollMonkey GreaseMonkey version; it’s only triggered when you click it, so no unnecessary overhead. It would still make sense to make it more generic so you could navigate to the next paragraph, heading, etc. With jQuery under the hood this would be easy to do and I’ll do it if there’s demand for it.

And thanks to FriendFeed from whom I stole most of the idea for the bookmarklet.

ScrollMonkey: Google Reader Style J-K Hotkeys For Image Paging And Centering

15

I’ve long wished for Google Reader style hotkeys (hitting “j” to move to the next item, “k” to go to the previous) to be available in more places. In particular, pages with many images are screaming for it – it’s just silly to keep messing with the scroll bar to get each image to line up properly in the viewable portion of the browser. If you don’t know what I mean go to any of these pages with lots of images and try to view each image. If you’re not frustrated with the scroll bar by the 3rd image you’re far more patient than I.

I finally found a few minutes to hack at it, and sure enough, it was quite easy to do with GreaseMonkey and jQuery.

The script does a very simple thing – it brings the next image to the top of the browser window so you can see it. You hit “j” to see the next image and “k” to go back to the previous.

Install GreaseMonkey and then install ScrollMonkey by clicking on it.

Once installed, go to any of the above pages with images, click on the page (to ensure the page is in focus), and hit the “j” key a couple of times until the first picture is at the top of the browser window. Now hit “j” again to go to the next image and “k” to go back.

The script is very simple and brain dead – I’ve made no attempt to make it intelligent. In particular, it’s active on every page and it downloads jQuery, which is probably more overhead than you want to have. In my case I typically have GreaseMonkey turned off and only turn it on when I need it, so it’s not much of a problem. It also looks at all images instead of attempting to find the large images of interest.

It would also be smart to generalize it to deal with anything – paragraphs, headings, etc – instead of just images.

And it’d be probably be nice to have it turn on via a hotkey instead of always being on, and it probably will interfere with any forms you’ll try to fill out.

But practically speaking none of these are problems I run into, so I’ll leave them for now and fix them if there’s any demand for it.

Give it a try and let me know what you think.

Here’s the code in its entirety, for those interested:


// Add jQuery
var GM_JQ = document.createElement('script');
GM_JQ.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js';
GM_JQ.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(GM_JQ);  

 // Check if jQuery's loaded
function GM_wait() {
	if(typeof unsafeWindow.jQuery == 'undefined') { window.setTimeout(GM_wait,100); }
	else { $ = unsafeWindow.jQuery; run(); }
}
GM_wait();  

function run() {
	var images = $('img'),
		idx = -1,
		nimages = images.length;
	$(document).keypress(function (e) {
		// j == 106 ; k == 107
		if (e.which != 106 && e.which != 107) { return; }
		if (e.which == 106 && idx < nimages-1) { idx++; }
		if (e.which == 107 && idx > 0) { idx--; }
		var top = $(images[idx]).offset().top;
		unsafeWindow.scrollTo(0, top);
	} );
}

Already Using Chrome Regularly

0

I’m surprised to find I use Chrome pretty regularly already. It’s mostly my interface to Gmail, Google Reader, and GCal, and sits quietly in the task bar until I need to check email. Lack of firebug and various other extensions prevent me from using it for everything, but it’s part of the regular line-up of apps.

Drizzle: MySQL Based Slim / Cloud-Oriented DB

1

Drizzle is interesting:

Drizzle: A High-Performance Microkernel DBMS for Scale-Out Applications
Drizzle is a community-driven project based on the popular MySQL DBMS that is focused on MySQL’s original goals of ease-of-use, reliability and performance.

Headed up by Brian Aker, Director of Architecture at MySQL AB. Take a look at the MySQL Differences page and you’ll mostly see features removed and cleaned up, which is great. Designed for high levels of concurrency, targeted to “cloud” applications. Monty and Brian’s posts offer motivation for the project.

Something to keep an eye on.

Python Generator Expressions

1

I wasn’t aware of generator expressions:


wwwlog     = open("access-log")
bytecolumn = (line.rsplit(None, 1)[1] for line in wwwlog)
bytes      = (int(x) for x in bytecolumn if x != '-')
print "Total", sum(bytes)

Similar to list comprehensions, but evaluated lazily. Voidspace describes it:

None of the generators are consumed until the final call to sum. As it iterates a line at a time (not keeping the log file in memory) it can handle huge log files – and as a bonus it runs faster than a typical solution with loops!

Neat.

Trying Google Chrome, So Far So Good

0

The Chrome download was surprisingly fast (as in, less than 5 seconds). FireFox options import during install didn’t work, but it’s been smooth sailing since then. It’s snappy and so far not buggy. Aesthetics of rendering web pages is good, seems better than FireFox. Quite fast too.

I remember thinking the Konqueror guys were crazy for writing yet another HTML renedering engine. That turned into WebKit, and now it’s in Safari, the iPhone, and Chrome. Amazing.

Google Chrome: Based on WebKit instead of Mozilla

0

Interesting that Google’s Chrome is based on WebKit instead of the Mozilla rendering engine…

Javascript Inheritance

0

Javascript inheritance is another one of those topics that always escapes my mind, so I’m recording it here for future reference.

I tried to get into Crockford’s Prototypal Inheritance method but I like the plain-old prototype inheritance without the object.create better. It’s entirely possible that I’m not quite getting Crockford’s method and its advantages; feel free to enlighten me by leaving a comment.

Anyway, here’s what I’m going with: We’ll have a base class (actually an object) English that says “hello” and “goodbye”. We’ll have a Spanglish class (actually an object) that inherits from English and says “ola” instead of “hello” (over-rides the hello method), but keeps saying “bye” (inherits the bye method from English).

The Spanglish.prototype = new English(); line does the actual inheritance by setting Spanglish’s prototype to be an instance of English.


function English() {
	this.hello = function(){ return "hello"; }
	this.bye   = function(){ return "bye"; }
}

function Spanglish() {
	this.hello = function() { return "ola"; }
}
Spanglish.prototype = new English();

e = new English();
s = new Spanglish();

e.hello();   // prints "hello"
e.bye();     // prints "bye"
s.hello();   // prints "ola"
s.bye();     // prints "bye", inherited from English