Ejemplo n.º 1
0
int cmd_playlist_add_track(int argc, char **argv)
{
	sp_link *plink, *tlink;
	sp_track *t;
	sp_playlist *pl;
	int i;
	struct pl_update_work *puw;

	if(argc < 4) {
		printf("add [playlist uri] [position] [track uri] <[track uri]>...\n");
		return 1;
	}

	plink = sp_link_create_from_string(argv[1]);
	if (!plink) {
		fprintf(stderr, "%s is not a spotify link\n", argv[1]);
		return -1;
	}

	if(sp_link_type(plink) != SP_LINKTYPE_PLAYLIST) {
		fprintf(stderr, "%s is not a playlist link\n", argv[1]);
		sp_link_release(plink);
		return -1;
	}

	puw = malloc(sizeof(struct pl_update_work));
	puw->position = atoi(argv[2]);
	puw->tracks = malloc(sizeof(sp_track *) * argc - 3);
	puw->num_tracks = 0;
	for(i = 0; i < argc - 3; i++) {
		tlink = sp_link_create_from_string(argv[i + 3]);
		if(tlink == NULL) {
			fprintf(stderr, "%s is not a spotify link, skipping\n", argv[i + 3]);
			continue;
		}
		if(sp_link_type(tlink) != SP_LINKTYPE_TRACK) {
			fprintf(stderr, "%s is not a track link, skipping\n", argv[i + 3]);
			continue;
		}
		t = sp_link_as_track(tlink);
		sp_track_add_ref(t);
		puw->tracks[puw->num_tracks++] = t;
		sp_link_release(tlink);
	}

	pl = sp_playlist_create(g_session, plink);
	if(!apply_changes(pl, puw)) {
		// Changes applied directly, we're done
		sp_playlist_release(pl);
		sp_link_release(plink);
		return 1;
	}

	fprintf(stderr, "Playlist not yet loaded, waiting...\n");
	sp_playlist_add_callbacks(pl, &pl_update_callbacks, puw);
	sp_link_release(plink);
	return 0;
}
Ejemplo n.º 2
0
void Spotify::changeCurrentlyPlayingSong()
{
    sp_track * track;
    const char * uri = currentURI.toLocal8Bit().constData();
    fprintf(stderr, "Spotify: Playing %s\n", uri);

    sp_link * link = sp_link_create_from_string(uri);
    if (!link) {
        fprintf(stderr, "Spotify: failed to parse URI (%s)\n", uri);
        currentURI.clear();
        return;
    }

    switch (sp_link_type(link)) {
    case SP_LINKTYPE_LOCALTRACK:
    case SP_LINKTYPE_TRACK:
        track = sp_link_as_track(link);
        if (!track) {
            fprintf(stderr, "Link is not a track\n");
            break;
        }
        nextTrack = track;
        sp_track_add_ref(track);
        tryLoadTrack();
        break;

    default:
        qDebug() << "URI is not a track:" << currentURI;
        break;
    }

    sp_link_release(link);
}
Ejemplo n.º 3
0
PHP_METHOD(Spotify, getArtistByURI)
{
        zval *uri, temp, *object = getThis();
        int timeout = 0;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &uri) == FAILURE) {
                return;
        }

        spotify_object *p = (spotify_object*)zend_object_store_get_object(object TSRMLS_CC);

        sp_link *link = sp_link_create_from_string(Z_STRVAL_P(uri));
        if (NULL == link) {
                RETURN_FALSE;
        }

        if (SP_LINKTYPE_ARTIST != sp_link_type(link)) {
                RETURN_FALSE;
        }

        sp_artist *artist = sp_link_as_artist(link);

        object_init_ex(return_value, spotifyartist_ce);
        SPOTIFY_METHOD2(SpotifyArtist, __construct, &temp, return_value, object, artist);

        sp_link_release(link);
}
Ejemplo n.º 4
0
sp_playlist *
sp_playlistcontainer_add_playlist(sp_playlistcontainer *pc, sp_link *link)
{
  sp_playlist *playlist = NULL;

  switch (sp_link_type(link))
  {
    case SP_LINKTYPE_PLAYLIST:
    case SP_LINKTYPE_STARRED:
      playlist = (sp_playlist *)sp_mock_registry_find(link->data);
      break;

    default: return NULL;
  }

  if (playlist)
  {
    sp_playlistcontainer_playlist_t container_playlist;

    container_playlist.playlist = playlist;
    container_playlist.type     = SP_PLAYLIST_TYPE_PLAYLIST;

    sp_mock_playlistcontainer_insert(pc, sp_playlistcontainer_num_playlists(pc), container_playlist);
  }

  return playlist;
}
Ejemplo n.º 5
0
QString Spotify::songNameFromUri(const QString &uriString)
{
    const char * uri = uriString.toLocal8Bit().constData();
    sp_link * link = sp_link_create_from_string(uri);
    if (!link) {
        fprintf(stderr, "Spotify: failed to parse URI (%s)\n", uri);
        return QString();
    }

    sp_track * track;
    QString song;

    switch (sp_link_type(link)) {
    case SP_LINKTYPE_LOCALTRACK:
    case SP_LINKTYPE_TRACK:
        track = sp_link_as_track(link);
        if (!track) {
            fprintf(stderr, "Link is not a track\n");
            break;
        }

        song = QString(sp_track_name(track));
        break;

    default:
        qDebug() << "URI is not a track:" << uriString;
        break;
    }

    sp_link_release(link);

    return song;
}
Ejemplo n.º 6
0
PHP_METHOD(Spotify, getAlbumByURI)
{
	zval *uri, temp, *object = getThis();
	int timeout = 0;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &uri) == FAILURE) {
		return;
	}

	spotify_object *p = (spotify_object*)zend_object_store_get_object(object TSRMLS_CC);

	sp_link *link = sp_link_create_from_string(Z_STRVAL_P(uri));
	if (NULL == link) {
		RETURN_FALSE;
	}

	if (SP_LINKTYPE_ALBUM != sp_link_type(link)) {
		RETURN_FALSE;
	}

	sp_album *album = sp_link_as_album(link);

	while (!sp_album_is_loaded(album)) {
		sp_session_process_events(p->session, &timeout);
	}

	object_init_ex(return_value, spotifyalbum_ce);
	SPOTIFY_METHOD2(SpotifyAlbum, __construct, &temp, return_value, object, album);

	sp_link_release(link);
}
Ejemplo n.º 7
0
sp_playlist *
sp_playlist_create(sp_session *UNUSED(session), sp_link *link)
{
  sp_linktype type = sp_link_type(link);

  if (type != SP_LINKTYPE_PLAYLIST && type != SP_LINKTYPE_STARRED)
  {
    return NULL;
  }

  return sp_mock_registry_find(link->data);
}
Ejemplo n.º 8
0
int luasp_link_type(lua_State *L) {
  // link_type = spotify.link_type(link)
  
  if (lua_gettop(L) != 1 || !lua_isuserdata(L, 1))
  {
    lua_pushstring(L, "incorrect argument to link_create_from_string(...)");
		lua_error(L);
  }
  
  lua_pushinteger(L, sp_link_type((sp_link*)lua_touserdata(L, 1)) );
  
  return 1;
}
Ejemplo n.º 9
0
void command_link(sp_session *session, const struct command * const command)
{
	sp_link *l = sp_link_create_from_string(command->search_string);

	if(l == NULL || sp_link_type(l) == SP_LINKTYPE_INVALID)
	{
		sock_send_str(command->sockfd, "Not a valid link.\n");
		return;
	}
	else if(sp_link_type(l) == SP_LINKTYPE_TRACK)
	{
		sp_track *t = sp_link_as_track(l);
		queue_add_track(t);
		sock_send_str(command->sockfd, "Added track to queue.\n");
	}
	else
	{
		sock_send_str(command->sockfd, "Link is valid but its type is not supported. Only links to tracks are supported.\n");
	}

	sp_link_release(l);
}
Ejemplo n.º 10
0
static void _spotify_play(sp_session *session, std::string uri)
{
    assert(pthread_equal(pthread_self(),g_spotify_tid));
    sp_link *l = sp_link_create_from_string(uri.c_str());
    sp_error err;
    int offset;
    if(!l || sp_link_type(l) != SP_LINKTYPE_TRACK) {
        return;
    }
    sp_track *t = sp_link_as_track_and_offset(l,&offset);
    try_play(session,t,offset);
    sp_link_release(l);
    return;
}
Ejemplo n.º 11
0
void QSpotifySession::handleUri(QString uri) {
    qDebug() << "QSpotifySession::handleUri";
    if (!m_isLoggedIn) {
        m_uriToOpen = uri;
        return;
    }
    sp_link *link = sp_link_create_from_string(uri.toLatin1().data());
    sp_linktype link_type = sp_link_type(link);
    if (link_type == SP_LINKTYPE_TRACK) {
        sp_track *track = sp_link_as_track(link);
        std::shared_ptr<QSpotifyTrack> q_track(new QSpotifyTrack(track, nullptr));
        enqueue(q_track);
        play(q_track, true);
    }
}
Ejemplo n.º 12
0
// ----------------------------------------------------------------------------
//
sp_linktype SpotifyEngine::getTrackLink( sp_track* track, CString& spotify_link ) 
{
    spotify_link.Empty();

    sp_link* link = sp_link_create_from_track( track, 0 );
    if ( link == NULL )
        return SP_LINKTYPE_INVALID;

    LPSTR spotify_link_ptr = spotify_link.GetBufferSetLength( 512 );
    sp_link_as_string ( link, spotify_link_ptr, 512 );

    sp_linktype link_type = sp_link_type( link );
    sp_link_release( link );

    return link_type;
}
Ejemplo n.º 13
0
int cmd_browse(int argc, char **argv)
{
	sp_link *link;

	if (argc != 2) {
		browse_usage();
		return -1;
	}

	
	link = sp_link_create_from_string(argv[1]);
	
	if (!link) {
		fprintf(stderr, "Not a spotify link\n");
		return -1;
	}

	switch(sp_link_type(link)) {
	default:
		fprintf(stderr, "Can not handle link");
		sp_link_release(link);
		return -1;

	case SP_LINKTYPE_ALBUM:
		sp_albumbrowse_create(g_session, sp_link_as_album(link), browse_album_callback, NULL);
		break;

	case SP_LINKTYPE_ARTIST:
		sp_artistbrowse_create(g_session, sp_link_as_artist(link), browse_artist_callback, NULL);
		break;

	case SP_LINKTYPE_TRACK:
		track_browse = sp_link_as_track(link);
		metadata_updated_fn = track_browse_try;
		sp_track_add_ref(track_browse);
		track_browse_try();
		break;

	case SP_LINKTYPE_PLAYLIST:
		browse_playlist(sp_playlist_create(g_session, link));
		break;
	}

	sp_link_release(link);
	return 0;
}
Ejemplo n.º 14
0
bool json_to_track(json_t *json, sp_track **track) {
  if (!json_is_string(json))
    return false;

  sp_link *link = sp_link_create_from_string(json_string_value(json));

  if (link == NULL)
    return false;

  if (sp_link_type(link) != SP_LINKTYPE_TRACK) {
    sp_link_release(link);
    return false;
  }

  *track = sp_link_as_track(link);
  return *track != NULL;
}
Ejemplo n.º 15
0
static PyObject *
Link_type(Link * self)
{
    return Py_BuildValue("i", sp_link_type(self->_link));
}
Ejemplo n.º 16
0
int cmd_playlist_offline(int argc, char **argv)
{
	sp_link *plink;
	sp_playlist *pl;
	int on;

	if (argc == 2 && !strcmp(argv[1], "status")) {
		printf("Offline status\n");
		printf("  %d tracks to sync\n",
		    sp_offline_tracks_to_sync(g_session));
		printf("  %d offline playlists in total\n",
		    sp_offline_num_playlists(g_session));
		return 1;
	}


	if (argc != 3) {
		printf("offline status | <playlist uri> <on|off>\n");
		return 1;
	}


	plink = sp_link_create_from_string(argv[1]);
	if (!plink) {
		fprintf(stderr, "%s is not a spotify link\n", argv[1]);
		return -1;
	}

	if (sp_link_type(plink) != SP_LINKTYPE_PLAYLIST) {
		fprintf(stderr, "%s is not a playlist link\n", argv[1]);
		sp_link_release(plink);
		return -1;
	}


	pl = sp_playlist_create(g_session, plink);

	if (argc == 3) {

		if (!strcasecmp(argv[2], "on"))
			on = 1;
		else if (!strcasecmp(argv[2], "off"))
			on = 0;
		else {
			fprintf(stderr, "Invalid mode: %s\n", argv[2]);
			return -1;
		}

		sp_playlist_set_offline_mode(g_session, pl, on);

	} else {

		sp_playlist_offline_status s;
		s = sp_playlist_get_offline_status(g_session, pl);

		printf("Offline status for %s (%s)\n",
		    argv[1], sp_playlist_name(pl));

		printf("  Status: %s\n", offlinestatus[s]);
		if (s == SP_PLAYLIST_OFFLINE_STATUS_DOWNLOADING)
			printf("    %d%% Complete\n",
			    sp_playlist_get_offline_download_completed(g_session, pl));
	}

	sp_playlist_release(pl);
	sp_link_release(plink);
	return 1;
}
Ejemplo n.º 17
0
static void restore_state(session_callback_type type, gpointer data, gpointer user_data) {
    JsonParser* jp = NULL;
    JsonReader* jr = NULL;

    const gchar* sqs;
    saved_state* s = NULL;

    GError* err = NULL;

    /* Is it the callback we're interested in? */
    if (type != SPOP_SESSION_LOGGED_IN)
        return;

    /* First disable the callback so it's not called again */
    session_remove_callback(restore_state, NULL);

    g_debug("savestate: reading saved state...");
    s = g_new0(saved_state, 1);

    /* Read and parse state file */
    jp = json_parser_new();
    if (!json_parser_load_from_file(jp, g_state_file_path, &err)) {
        g_warning("savestate: error while reading state file: %s", err->message);
        goto restorestate_error;
    }

    jr = json_reader_new(json_parser_get_root(jp));

    /* Read basic state */
    if (!json_reader_read_member(jr, "status")) goto restorestate_jr_error;
    sqs = json_reader_get_string_value(jr);
    json_reader_end_member(jr);
    if      (strcmp(sqs, "stopped")) s->qs = STOPPED;
    else if (strcmp(sqs, "playing")) s->qs = PLAYING;
    else if (strcmp(sqs, "paused"))  s->qs = PAUSED;
    else {
        g_warning("savestate: bad value for queue status: %s", sqs);
        goto restorestate_error;
    }

    if (!json_reader_read_member(jr, "repeat")) goto restorestate_jr_error;
    s->repeat = json_reader_get_boolean_value(jr);
    json_reader_end_member(jr);

    if (!json_reader_read_member(jr, "shuffle")) goto restorestate_jr_error;
    s->shuffle = json_reader_get_boolean_value(jr);
    json_reader_end_member(jr);

    if (!json_reader_read_member(jr, "current_track")) goto restorestate_jr_error;
    s->cur_track = json_reader_get_int_value(jr);
    json_reader_end_member(jr);

    /* Now read tracks URIs */
    if (!json_reader_read_member(jr, "tracks")) goto restorestate_jr_error;
    if (!json_reader_is_array(jr)) {
        g_warning("savestate: error while parsing JSON: tracks is not an array");
        goto restorestate_error;
    }
    gint tracks = json_reader_count_elements(jr);
    if (s->cur_track >= tracks) {
        g_warning("savestate: incoherent state file: cur_track >= tracks");
        goto restorestate_error;
    }

    s->tracks = g_array_sized_new(FALSE, FALSE, sizeof(sp_track*), tracks);
    if (!s->tracks)
        g_error("Can't allocate array of %d tracks.", tracks);

    size_t i;
    gboolean can_restore_now = TRUE;
    for (i=0; i < tracks; i++) {
        json_reader_read_element(jr, i);
        const gchar* uri = json_reader_get_string_value(jr);
        json_reader_end_element(jr);

        sp_link* lnk = sp_link_create_from_string(uri);
        sp_linktype lt = sp_link_type(lnk);
        if (lt != SP_LINKTYPE_TRACK) {
            g_warning("savestate: invalid link type for track %zu: %d", i, lt);
            sp_link_release(lnk);
            goto restorestate_error;
        }
        sp_track* tr = sp_link_as_track(lnk);
        sp_track_add_ref(tr);
        sp_link_release(lnk);
        g_array_append_val(s->tracks, tr);
        if (!sp_track_is_loaded(tr))
            can_restore_now = FALSE;
    }

    /* If possible, restore now, else wait for all tracks to be loaded */
    if (can_restore_now)
        really_restore_state(s);
    else {
        g_timeout_add(100, (GSourceFunc) really_restore_state, s);
        g_debug("savestate: waiting for all tracks to be loaded before restoring saved state...");
    }

    /* Add a notification callback */
    if (!interface_notify_add_callback(savestate_notification_callback, NULL))
        g_error("Could not add savestate callback.");

    goto restorestate_clean;

 restorestate_jr_error:
    err = (GError*) json_reader_get_error(jr);
    g_warning("savestate: error while parsing JSON: %s", err->message);

 restorestate_error:
    if (s) {
        if (s->tracks)
            g_array_free(s->tracks, TRUE);
        g_free(s);
    }

 restorestate_clean:
    if (jp)
        g_object_unref(jp);
    if (jr)
        g_object_unref(jr);
}
Ejemplo n.º 18
0
// Request dispatcher
static void handle_request(struct evhttp_request *request,
                            void *userdata) {
  evhttp_connection_set_timeout(request->evcon, 1);
  evhttp_add_header(evhttp_request_get_output_headers(request),
                    "Server", "[email protected]/spotify-api-server");

  // Check request method
  int http_method = evhttp_request_get_command(request);

  switch (http_method) {
    case EVHTTP_REQ_GET:
    case EVHTTP_REQ_PUT:
    case EVHTTP_REQ_POST:
      break;

    default:
      evhttp_send_error(request, HTTP_NOTIMPL, "Not Implemented");
      return;
  }

  struct state *state = userdata;
  sp_session *session = state->session;
  char *uri = evhttp_decode_uri(evhttp_request_get_uri(request));

  char *entity = strtok(uri, "/");

  if (entity == NULL) {
    evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request");
    free(uri);
    return;
  }

  // Handle requests to /user/<user_name>/inbox
  if (strncmp(entity, "user", 4) == 0) {
    char *username = strtok(NULL, "/");

    if (username == NULL) {
      evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request");
      free(uri);
      return;
    }

    char *action = strtok(NULL, "/");
    handle_user_request(request, action, username, session);
    free(uri);
    return;
  }

  // Handle requests to /playlist/<playlist_uri>/<action>
  if (strncmp(entity, "playlist", 8) != 0) {
    evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request");
    free(uri);
    return;
  }

  char *playlist_uri = strtok(NULL, "/");

  if (playlist_uri == NULL) {
    switch (http_method) {
      case EVHTTP_REQ_PUT:
      case EVHTTP_REQ_POST:
        put_playlist(NULL, request, session);
        break;

      default:
        send_error(request, HTTP_BADREQUEST, "Bad Request");
        break;
    }

    free(uri);
    return;
  }

  sp_link *playlist_link = sp_link_create_from_string(playlist_uri);

  if (playlist_link == NULL) {
    send_error(request, HTTP_NOTFOUND, "Playlist link not found");
    free(uri);
    return;
  }

  if (sp_link_type(playlist_link) != SP_LINKTYPE_PLAYLIST) {
    sp_link_release(playlist_link);
    send_error(request, HTTP_BADREQUEST, "Not a playlist link");
    free(uri);
    return;
  }

  sp_playlist *playlist = sp_playlist_create(session, playlist_link);
  sp_link_release(playlist_link);

  if (playlist == NULL) {
    send_error(request, HTTP_NOTFOUND, "Playlist not found");
    free(uri);
    return;
  }

  sp_playlist_add_ref(playlist);

  // Dispatch request
  char *action = strtok(NULL, "/");

  // Default request handler
  handle_playlist_fn request_callback = &not_implemented;
  void *callback_userdata = session;

  switch (http_method) {
  case EVHTTP_REQ_GET:
    {
      if (action == NULL) {
        // Send entire playlist
        request_callback = &get_playlist;
      } else if (strncmp(action, "collaborative", 13) == 0) {
        request_callback = &get_playlist_collaborative;
      } else if (strncmp(action, "subscribers", 11) == 0) {
        request_callback = &get_playlist_subscribers;
      }
    }
    break;

  case EVHTTP_REQ_PUT:
  case EVHTTP_REQ_POST:
    {
      if (strncmp(action, "add", 3) == 0) {
        request_callback = &put_playlist_add_tracks;
      } else if (strncmp(action, "remove", 6) == 0) {
        request_callback = &put_playlist_remove_tracks;
      } else if (strncmp(action, "patch", 5) == 0) {
        callback_userdata = state;
        request_callback = &put_playlist_patch;
      }
    }
    break;
  }

  if (sp_playlist_is_loaded(playlist)) {
    request_callback(playlist, request, callback_userdata);
  } else {
    // Wait for playlist to load
    register_playlist_callbacks(playlist, request, request_callback,
                                &playlist_state_changed_callbacks,
                                callback_userdata);
  }

  free(uri);
}
Ejemplo n.º 19
0
static void put_playlist_patch(sp_playlist *playlist,
                               struct evhttp_request *request,
                               void *userdata) {
  struct state *state = userdata;
  struct evbuffer *buf = evhttp_request_get_input_buffer(request);
  size_t buflen = evbuffer_get_length(buf);

  if (buflen == 0) {
    send_error(request, HTTP_BADREQUEST, "No body");
    return;
  }

  // Read request body
  json_error_t loads_error;
  json_t *json = read_request_body_json(request, &loads_error);

  if (json == NULL) {
    send_error(request, HTTP_BADREQUEST,
               loads_error.text ? loads_error.text : "Unable to parse JSON");
    return;
  }

  if (!json_is_array(json)) {
    json_decref(json);
    send_error(request, HTTP_BADREQUEST, "Not valid JSON array");
    return;
  }

  // Handle empty array
  int num_tracks = json_array_size(json);

  if (num_tracks == 0) {
    send_reply(request, HTTP_OK, "OK", NULL);
    return;
  }

  sp_track **tracks = calloc(num_tracks, sizeof (sp_track *));
  int num_valid_tracks = 0;

  for (int i = 0; i < num_tracks; i++) {
    json_t *item = json_array_get(json, i);

    if (!json_is_string(item)) {
      json_decref(item);
      continue;
    }

    char *uri = strdup(json_string_value(item));
    sp_link *track_link = sp_link_create_from_string(uri);
    free(uri);

    if (track_link == NULL)
      continue;

    if (sp_link_type(track_link) != SP_LINKTYPE_TRACK) {
      sp_link_release(track_link);
      continue;
    }

    sp_track *track = sp_link_as_track(track_link);

    if (track == NULL)
      continue;

    tracks[num_valid_tracks++] = track;
  }

  json_decref(json);

  // Bail if no tracks could be read from input
  if (num_valid_tracks == 0) {
    send_error(request, HTTP_BADREQUEST, "No valid tracks");
    free(tracks);
    return;
  }

  tracks = realloc(tracks, num_valid_tracks * sizeof (sp_track *));

  // Apply diff
  apr_pool_t *pool = state->pool;
  svn_diff_t *diff;
  svn_error_t *diff_error = diff_playlist_tracks(&diff, playlist, tracks,
                                                 num_valid_tracks, pool);

  if (diff_error != SVN_NO_ERROR) {
    free(tracks);
    svn_handle_error2(diff_error, stderr, false, "Diff");
    send_error(request, HTTP_BADREQUEST, "Search failed");
    return;
  }

  svn_error_t *apply_error = diff_playlist_tracks_apply(diff, playlist, tracks,
                                                        num_valid_tracks,
                                                        state->session);

  if (apply_error != SVN_NO_ERROR) {
    free(tracks);
    svn_handle_error2(apply_error, stderr, false, "Updating playlist");
    send_error(request, HTTP_BADREQUEST, "Could not apply diff");
    return;
  }

  if (!sp_playlist_has_pending_changes(playlist)) {
    free(tracks);
    get_playlist(playlist, request, NULL);
    return;
  }

  free(tracks);
  register_playlist_callbacks(playlist, request, &get_playlist,
                              &playlist_update_in_progress_callbacks, NULL);
}
Ejemplo n.º 20
0
void AudioHTTPServer::sid( QxtWebRequestEvent* event, QString a )
{
    qDebug() << QThread::currentThreadId() << "HTTP" << event->url.toString() << a;

    if( !SpotifySession::getInstance()->Playback()->trackIsOver() ) {
        SpotifySession::getInstance()->Playback()->endTrack();
    }

    // the requested track
    QString uid = a.replace( ".wav", "");
//    qDebug() << QThread::currentThreadId() << "Beginning to stream requested track:" << uid;
    if( uid.isEmpty() || !sApp->hasLinkFromTrack( uid ) ) {
        qWarning() << "Did not find spotify track UID in our list!" << uid;
        sendErrorResponse( event );

        return;
    }

    // get the sp_track
    sp_link* link = sApp->linkFromTrack( uid );

    sp_track* track = sp_link_as_track( link );
    if( !track ) {
        qWarning() << QThread::currentThreadId() << "Uh oh... got null track from link :(" << sp_link_type( link );
        sendErrorResponse( event );
        return;
    }
    if( !sp_track_is_loaded( track ) ) {
        qWarning() << QThread::currentThreadId() << "uh oh... track not loaded yet! Asked for:" << sp_track_name( track );
        m_savedEvent = event;
        m_savedTrack = track;
        QTimer::singleShot( 250, this, SLOT( checkForLoaded() ) );
        return;

    } else {
        startStreamingResponse( event, track );
    }
}