Thursday, February 26, 2009

New Widgets

We released a few new player widgets today behind the scenes to test a few things out before we integrate them fully into sharing. Give them a try and let us know where you like them or not. To get the album or song id, just go to the share page for the song or album and get the last param on the URL. For example, the album id is DMcjWV2ZhPsx.


Single Song


Monday, February 02, 2009

Blitzen Trapper Release

The Blitzen Trapper release is now up and running on production. This release includes several bug fixes as well as:

  • Improved album pages - much better handling of compilations and a cleaner layout

  • Song pages - extended information for individual tracks is now available. See who's been listening to this track, RECs for the song, and similar songs. More importantly, it means when you find a new track your friend doesn't have to search throuhg the album page to find which one you re actually talking about.

  • Latest Albums RSS - Much requested and extremely useful

  • Beta Site - back up and running. Will be pushing some new things we've been working on out soon

Wednesday, December 10, 2008

Erlounge NYC on Thursday

The first (afaik?) meeting of Erlounge NYC is this coming Thursday 12/11/08 at 7:30pm at The Golden Unicorn in Chinatown, on the 3rd floor.

If there's anyone out there interested in learning more about Erlang (or you're already an Erlang hacker and want to meet others) come join us!

Monday, November 24, 2008

Scrobble from Amie Street to Your Account

In the latest production update, we finally pushed out the code to scrobble anything you listen to on Amie Street, whether its from the bottom player, popout player, library player, or any widgets, to your account. Along with the standard scrobbling, your now playing status will also be updated every time you start a playing a song on Amie Street.

To enable scrobbling, click on the "Account" tab on Amie Street and at the bottom under "Other Services", click on the " Settings" link.

You can also join us in the group.

Monday, October 20, 2008

Delayed selectors in jQuery

On our new redesign we're doing a lot of crazy JavaScript and have come up with some interesting solutions to interesting problems. Today I was working on a problem where hitting the "play" button for a song before the player SWF had loaded caused a JS error on the page. It was trying to call a JS method on the swf, but the method didn't exist yet.

I came up with this interesting solution which is extensible and reusable for a lot of use cases. Here's a concise illustration of the technique:

<script src=""></script>
google.load("jquery", "1");
google.setOnLoadCallback(function() {

DelayProxy = function(sel) {
this.sel = sel;
var self = this;
this.interval = setInterval(function() { self.try(); }, 100);

DelayProxy.prototype = {
queue: [],
'__noSuchMethod__': function(id, args) {
this.queue.push([id, args]);

'try': function() {
var res = $(this.sel);
if (res.length) {
for each (var call in this.queue) {
res[call[0]].apply(res, call[1]);

$.whenAvailable = function(target) {
var els = $(target);
if (els.length) {
return els;
} else {
return new DelayProxy(target);

$('#run-test').click(function() {
$.whenAvailable('#target').attr('value', "hello world!");

$('#make-target').click(function() {
$('body').append('<input type="text" id="target">');


<a href="#" id="run-test">Set target value</a>
<a href="#" id="make-target">Make target</a>


You can try this demo here. First click "make target" and then "set target value". Nothing special going on - we're inserting a text field into the DOM, then setting its value using the jQuery attr function. Now reload the page so the inserted field goes away and hit the links in the opposite order. As soon as you hit "make target" the delayed "set target value" call should execute.

The real trick behind this code is the __noSuchMethod__ function. If an object has this property set to a function, it will be called for any missing member function call, and will receive the function name and arguments as arguments. It's similar to PHP's __call or perl's AUTOLOAD and comes in really handy. Here's how the code works:

  • When you call $.whenAvailable, it checks with jQuery to see if the selector has any matching elements. Since it doesn't, it returns a new DelayProxy object. The constructor of the DelayProxy sets up a timer which calls try every 100ms.

  • When you call attr(...) on the DelayProxy, it fires the __noSuchMethod__ function. This pushes onto the internal queue.

  • When you later hit the "Make target" button, the selector becomes valid

  • Some amount of time (<100ms) later, the timer fires and DelayProxy.try finds the selector. This kills itself (clearTimeout) and then applies the queued up function(s) to the resulting selector.

Pretty neat! I used to hate JS, but it does have some pretty powerful tricks.

update: it turns out this is a Mozilla SpiderMonkey extension, and hence not really useful in the real world. Boo!! The same idea still applies, but you've got to manually register the function for each of the functions to be delayed.

Thursday, September 25, 2008

Flex Tree Component Bug

Yesterday I encountered a bug with setting the selectedIndex of the Flex tree component. The default behavior for dropping an item onto a Tree, or any List control, is to drop items in between the items currently in the list. I, however, wanted to drop items onto the items currently in the list. One common way to do this is to set a handler for the dragOver event of the Tree and in this handler call calculateDropIndex on the Tree and set the Tree's selectedIndex equal to this result. This gives some nice visual feedback and lets you easily get access to the element in the Tree at the target drop location.

The problem I encountered manifests itself when a new item is added to the Tree. In particular, if the dataProvider of the Tree is an Array, there seems to be an off-by-one error when dragging over the elements of the Tree after an element has been added to the underlying Array. If you use an ArrayCollection as the dataProvider for the Tree, everything works fine.

In the demo below, try dragging any of the elements in the two Trees over the other elements in the Tree. All seems to work. Now reset the demo, and click the "Add Item" button for the Tree on the right (the one backed by the ArrayCollection.) Note that it continues to work as expected. Now try to do the same thing with the Tree on the left. After doing a fresh reset and clicking "Add Item", good luck trying to drop something onto the element with label "5".

After doing a small amount of debugging, I've come to the conclusion that the calculateDropIndex method is always returning the right value, but that setting selectedIndex is not correctly finding the right element in the Tree.

You can check out the source for this here.

Thursday, September 18, 2008

How to fix: slashes urlencoded as %2F giving 404 in Apache

I ran into a problem today where URLs that contained "%2F" in them were giving 404s in Apache. By enabling mod_rewrite logging it became evident that Apache was short circuiting the request even before entering the module.

After some googling I came upon the AllowEncodedSlashes directive. I have no idea why this is off by default, but it fixes the problem.