Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 6 commits
  • 4 files changed
  • 0 commit comments
  • 2 contributors
View
30 spartify/handlers.py
@@ -10,23 +10,41 @@ def wrap(self, party_id, *args, **kwargs):
class API(object):
def start(self):
- return party.create()
+ party_id, queue, version = party.create()
+ return {
+ 'id': party_id,
+ 'queue': queue,
+ 'version': version,
+ }
@validate
def join(self, party_id):
- return party.join(party_id)
+ guest_id, (queue, version,) = party.join(party_id)
+ return {
+ 'guest': guest_id,
+ 'queue': queue,
+ 'version': version,
+ }
@validate
- def queue(self, party_id):
- return party.Party(party_id).get_queue()
+ def queue(self, party_id, version=None):
+ result = party.Party(party_id).get_queue(version)
+ if result:
+ queue, version = result
+ return {
+ 'queue': queue,
+ 'version': version,
+ }
@validate
def pop(self, party_id):
- return party.Party(party_id).pop_track()
+ party.Party(party_id).pop_track()
+ return None
@validate
def vote(self, party_id, user_id, track_uri):
- return party.Party(party_id).vote(user_id, track_uri)
+ party.Party(party_id).vote(user_id, track_uri)
+ return None
class SpartifyService(API, util.JsonService):
View
14 spartify/party.py
@@ -24,11 +24,17 @@ def pop_track(self):
self._queue.add(t, 0)
return track.to_dict()
- def get_queue(self):
- return [x.to_dict() for x in self._queue.all]
+ def get_queue(self, version=None):
+ if version and not version < self._queue.version:
+ # No changes to the queue
+ return
+ return [x.to_dict() for x in self._queue.all], self._queue.version
def get_played(self):
- return [t.to_dict() for t in self._played.all]
+ if version and not version < self._played.version:
+ # No changes to the queue
+ return
+ return [x.to_dict() for x in self._played.all], self._played.version
def vote(self, user, track_uri):
user_vote_key = 'vote:%s:%s' % (user, track_uri,)
@@ -44,7 +50,7 @@ def create():
party_id = create_id(size=5)
key = 'party:%s' % (party_id,)
store.timeout_store(key, 1, config.PARTY_JOIN_TIMEOUT)
- return party_id, []
+ return party_id, [], '0'
def join(party_id):
return create_id(), Party(party_id).get_queue()
View
14 spartify/playback.py
@@ -3,6 +3,7 @@
from spartify.stores import store
from spartify.util import index_of
from spartify.track import Track
+from time import time
class BaseQueue(object):
@@ -12,12 +13,19 @@ def __init__(self, party_id):
def _load(self):
try:
- self._queue = store[self._key]
+ data = store[self._key]
+ if len(data) > 0 and type(data[0] is str):
+ # backwards compatible...
+ self.version, self._queue = store[self._key]
+ else:
+ self.version, self._queue = '0', data
except KeyError:
- self._queue = []
+ self.version, self._queue = '0', []
def _save(self):
- store.timeout_store(self._key, self._queue, config.PARTY_EXPIRE_TIMEOUT)
+ self.version = str(time())
+ store.timeout_store(self._key, (self.version, self._queue,),
+ config.PARTY_EXPIRE_TIMEOUT)
def __len__(self):
return len(self._queue)
View
94 static/spartify.js
@@ -1,66 +1,5 @@
var spartify = function () {
- // A mock API for testing.
- function MockApi() {
- this.mock_songs_ = [];
- }
- MockApi.prototype.createParty = function (success, error) {
- console.log('MockApi: createParty');
- setTimeout(function () {
- success('ABCDEFG1234');
- }, 300);
- };
- MockApi.prototype.joinParty = function (partyCode, success, error) {
- console.log('MockApi: joinParty', partyCode);
- setTimeout(function () {
- success({user_id: 'USERID123', songs: [
- {album: 'Test Album', artist: 'Test Artist', length: 100, title: 'Title #1', uri: 'abc'},
- {album: 'Test Album', artist: 'Test Artist', length: 100, title: 'Title #2', uri: 'def'}
- ]});
- }, 300);
- };
- MockApi.prototype.getSongs = function (partyCode, success, error) {
- console.log('MockApi: getSongs', partyCode);
- var t = this;
- setTimeout(function () {
- success(t.mock_songs_);
- }, 300);
- };
- MockApi.prototype.pop = function (partyCode, success, error) {
- console.log('MockApi: pop', partyCode);
- var t = this;
- setTimeout(function () {
- success(t.mock_songs_.unshift());
- }, 300);
- };
- MockApi.prototype.vote = function (partyCode, userId, uri, success, error) {
- console.log('MockApi: vote', partyCode, userId, uri);
- var t = this;
- setTimeout(function () {
- var i;
- if (Math.random() < 0.3 && t.mock_songs_.length > 1) {
- i = Math.floor(Math.random() * (t.mock_songs_.length - 1));
- var song = t.mock_songs_[i];
- t.mock_songs_[i] = t.mock_songs_[i + 1];
- t.mock_songs_[i + 1] = song;
- }
-
- var add = true;
- for (i = 0; i < t.mock_songs_.length; i++) {
- if (t.mock_songs_[i] == uri) {
- add = false;
- break;
- }
- }
- if (add) t.mock_songs_.push({album: 'Test Album', artist: 'Test Artist', length: 100, title: 'Title', uri: uri});
-
- success();
- }, 300);
- };
-
-
- // The real API.
- function Api() {
- }
+ function Api() {}
Api.createHandler = function (method, argNames, callback) {
return function () {
if (arguments.length - 2 != argNames.length) {
@@ -133,14 +72,13 @@ var spartify = function () {
return {
- //api: new MockApi()
api: new Api()
};
}();
// Interface code.
(function () {
- var partyCode, timeout, playing, queue, queueVersion;
+ var partyCode, playing, queue, queueVersion;
function clearState() {
partyCode = null;
@@ -196,7 +134,7 @@ var spartify = function () {
$(window).scrollTop(0);
if (page != 'party') {
- clearTimeout(timeout);
+ stopGetSongs();
clearState();
}
}
@@ -267,7 +205,9 @@ var spartify = function () {
},
complete: function () {
spartify.api.pop(getPartyCode(),
- null,
+ function () {
+ deferGetSongs();
+ },
null);
}
});
@@ -282,8 +222,7 @@ var spartify = function () {
var container = $('#queue');
function songsCallback(data) {
- clearTimeout(timeout);
- timeout = setTimeout(getSongs, 5000);
+ deferGetSongs(5000);
// The API won't return any data if there was no update.
if (!data) return;
@@ -298,9 +237,12 @@ var spartify = function () {
function vote(song) {
spartify.api.vote(getPartyCode(), getUserId() || 'NO_USER_ID', song.uri,
- null,
+ function () {
+ deferGetSongs();
+ },
function () {
queueVersion = undefined;
+ deferGetSongs();
});
// Simulate the addition of the track to make UI feel snappier.
@@ -313,6 +255,20 @@ var spartify = function () {
$('#party-room h2').toggle(queue.length > 0);
}
+ var stopGetSongs, deferGetSongs;
+ (function () {
+ var timeout;
+
+ deferGetSongs = function (delay) {
+ stopGetSongs();
+ timeout = setTimeout(getSongs, delay || 150);
+ }
+
+ stopGetSongs = function () {
+ clearTimeout(timeout);
+ }
+ })();
+
function getSongs() {
var code = getPartyCode();
if (!code) return;

No commit comments for this range

Something went wrong with that request. Please try again.