Automatically creat chat log dir (see #916)

Create chat log dir automatically, in case it doesn't exist.

Notes:

* This fixes the main cause of the common "oops" in new deployments.
* Also use a saner djangoauth default, and update readme accordingly.
Fix error propagation from chat (fixes #917)

When the new user-friendly oops message was implemented, the chat plugin
was not updated to take proper advantage of it.  As a consequence,
poll_plugin errors would not contain the necessary player_id to restart
said poll after display of the warning modal.

Ultimately, this which would cause an infinite loop of exceptions
server-side, since the player_id is necessary for authentication.

Notes:

* There were a few places beyond the actual client-side chat plugin
  where the player_id propagation was missing.  They were fixed.

* So as not to mask real errors behind an avalanche of
  player_id=undefined server-side exceptions, the poll_plugin is not
  restarted after an oops if player_id is not set.
Implement service tab_added/removed callbacks (closes #914).

This implements two new service "notifications".

When a tab is associated with a player in the tabs table, the listeners
are notified with a 'tab_added' type notification.
Similarly, when a tab is removed, they are notified with a 'tab_removed'
type notification.

I changed the tabInteraction to return an additional value which is
a boolean indicating whether the current game was added to the tabs
table (as opposed to not being added because it was already associated
with the player in the tabs table before this request).
I did this rather than calling service.notify directly inside the tabsInteraction
method because I figured it wouldn't be a good idea to fire notifications
while a DB transaction hasn't even finished yet.
Merge branch 'master' of git://gitorious.org/~arbrandes/cardstories/arbrandes-cardstories
Hook the table plugin into tab notifications to implement (closes #918).

This wires together the final pieces to implement story #787 (Detect when
the next author is not participating to a table anymore).

Since the table plugin was already reacting to player disconnect events
emitted by the activity plugin, adding a hook for a closed tab event
wasn't very hard as it reuses most of the code for handling disconnects.

I had some more trouble with twisted tests, though. To make the tests
work, I removed the helper methods start_table_poll and check_poll
that used mocks and instead used 'raw' poll mechanism. The advantage
of this is that it is possible to "block" the test waiting for the
poll to fire by yeilding to the poll. The problem I was seeing with
the mocked version was race conditions when checking whether the poll
has returned at a certain point in the test. Explicitly blocking until
the poll returns solves this issue, and makes the flow of the test
simpler to follow, IMHO.
Refactor the tab related service methods (closes #919).

The metods for opening and closing tabs went through a minor refactoring
so that they make more sense and are a bit easier to follow.

There is now also a service.get_opened_tabs(player_id) method which
returns a list of all opened tabs by a player, and doesn't do any other
magic under the hood.

The method that was called service.get_tab_game_ids previously and would
magically add the current game to opened tabs was renamed to
service.get_opened_tabs_from_args, which is a poor name and I would appreciate
any better suggestions.

Another method with a bad name is service.remove_tab, becaues it is easily confused
with service.close_tab. The difference between these to is that close_tab is just
a function that takes a player_id and a game_id and does what it says.
The remove_tab method on the other hand is an HTTP endpoint that the
JS client hits when the player closes the tab.
Again, suggestions for better names would be much appreciated (I am bad at this).

I also renamed the 'tab_added' and 'tab_removed' notifications to
'tab_opened' and 'tab_closed', which I think sounds better and makes more sense.
Better synchronize sounds on results page (refs #922).

I made the score_bell sound start playing a bit before the star
hits the end of the level bar, so that when the sound plays it isn't
too late already.

I also made the pinball sound start playing before the score
"slot machine" animation starts.
The pinball sound then keeps playing during the level bar animations
and is stopped when the level bar animations stop.
This probably isn't ideal (the slot machine animation is so
nice that it would deserve its own sound), but I tried a couple
of different combinations and this still seemed like the best
compromise.
Preload sound files via SoundManager's autoLoad option (close #920).

This creates all sound objects with the autoLoad option set to true.
This means that audio files will start loading as soon as the game
is loaded.

This creates a HTTP request for every sound at startup, but I think
we might be able to get away with this since we don't use too many
sound files, and all of them are quite small.

If it turns out this doesn't work well, sound manager offers options
for more fine-tuned preloading. We could probably even hook that into
the preloading screen for ultimate preload experience, but that would
require some more work.
Fix nasty bug when closing a tab in Firefox (closes #929).

The $.cardstories.send function was used from the tabs plugin,
and it wasn't called with the correct number of parameters
(I guess we forgot to update it when we were changing the
$.cardstories.send function).

The most problematic parameter that was missing was a callback
function, which $.cardstories.send invokes in a setTimeout.
Firefox seems to be mind this a lot since it throws an error
and stops execution, while most other browsers quietly ignore
this.

This commit fixes the tabs plugin to call send with the correct
number of arguments, while also making sure that send doesn't
try to invoke an undefined function in a setTimeout.
Debug missing player_info (refs #927)

Since for the life of me I couldn't reproduce the problem described on
issue 927, either locally or accessing the remote test.cardstories.org, with
or without bots, and from different browsers, this commits some code to
help debug the issue.

This will test two theories, enabling us to know what's going on:

1) That the table plugin is not returning a valid next_owner_id.

2) That the next_owner_id is valid but not in the players_info array.