示例#1
0
int cmd_playlist(int argc, char **argv)
{
	int index, i;
	sp_track *track;
	sp_playlist *playlist;
	sp_playlistcontainer *pc = sp_session_playlistcontainer(g_session);

	if (argc < 1) {
		printf("playlist [playlist index]\n");
		return 0;
	}

	index = atoi(argv[1]);
	if (index < 0 || index > sp_playlistcontainer_num_playlists(pc)) {
		printf("invalid index\n");
		return 0;
	}
	playlist = sp_playlistcontainer_playlist(pc, index);
	printf("Playlist %s by %s%s%s\n",
		   sp_playlist_name(playlist),
		   sp_user_display_name(sp_playlist_owner(playlist)),
		   sp_playlist_is_collaborative(playlist) ? " (collaborative)" : "",
		   sp_playlist_has_pending_changes(playlist) ? " with pending changes" : ""
		   );
	for (i = 0; i < sp_playlist_num_tracks(playlist); ++i) {
		track = sp_playlist_track(playlist, i);
		printf("%d. %c %s%s %s\n", i,
			   sp_track_is_starred(g_session, track) ? '*' : ' ',
			   sp_track_is_local(g_session, track) ? "local" : "     ",
			   sp_track_is_autolinked(g_session, track) ? "autolinked" : "          ",
			   sp_track_name(track));
	}
	return 1;
}
示例#2
0
// session->mutex must be locked
static int wait_for_playlist_pending_changes(php_spotify_playlist *playlist) {
	struct timespec ts;
	int err = 0;
	php_spotify_session *session;

	assert(playlist != NULL);
	session = playlist->session;

	DEBUG_PRINT("wait_for_playlist_pending_changes\n");

	// Block for a max of SPOTIFY_TIMEOUT seconds
	clock_gettime(CLOCK_REALTIME, &ts);
	ts.tv_sec += SPOTIFY_TIMEOUT;

	request_lock();

	while(err == 0) {
		DEBUG_PRINT("wait_for_playlist_pending_changes loop\n");
		int pending_changes;

		session_lock(session);
		pending_changes = sp_playlist_has_pending_changes(playlist->playlist);
		session_unlock(session);

		if (!pending_changes)
			break;

		// Wait until a callback is fired
		err = request_sleep_lock(&ts);
	}

	request_unlock();

	DEBUG_PRINT("wait_for_playlist_pending_changes end(%d)\n", err);
	return err;
}
示例#3
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);
}