Skip to content

Commit 0dc24b0

Browse files
committed
Add /user/<username>/playlists and /user/<username>/starred to get a users public playlists and starred playlist
1 parent 50ee2f1 commit 0dc24b0

File tree

2 files changed

+121
-24
lines changed

2 files changed

+121
-24
lines changed

json.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,14 @@ json_t *playlist_to_json(sp_playlist *playlist, json_t *object) {
4646
strlen("284on3DVWeAxWkgVuzZKGt") + 1;
4747
char *playlist_uri = malloc(playlist_uri_len);
4848

49-
if (playlist_uri == NULL) {
49+
if (playlist_uri == NULL)
5050
return NULL;
51-
}
5251

5352
sp_link *playlist_link = sp_link_create_from_playlist(playlist);
53+
54+
if (playlist_link == NULL) // Shouldn't happen; playlist is loaded (?)
55+
return object;
56+
5457
sp_link_as_string(playlist_link, playlist_uri, playlist_uri_len);
5558
sp_link_release(playlist_link);
5659
json_object_set_new(object, "uri",

server.c

+116-22
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@ struct playlist_handler {
8484
void *userdata;
8585
};
8686

87+
typedef void (*handle_playlistcontainer_fn)(sp_playlistcontainer *,
88+
struct evhttp_request *,
89+
void *);
90+
91+
struct playlistcontainer_handler {
92+
sp_playlistcontainer_callbacks *playlistcontainer_callbacks;
93+
struct evhttp_request *request;
94+
handle_playlistcontainer_fn callback;
95+
void *userdata;
96+
};
97+
8798
static void send_reply(struct evhttp_request *request,
8899
int code,
89100
const char *message,
@@ -153,6 +164,31 @@ void playlist_dispatch(sp_playlist *playlist, void *userdata) {
153164
free(handler);
154165
}
155166

167+
static struct playlistcontainer_handler *register_playlistcontainer_callbacks(
168+
sp_playlistcontainer *pc,
169+
struct evhttp_request *request,
170+
handle_playlistcontainer_fn callback,
171+
sp_playlistcontainer_callbacks *playlistcontainer_callbacks,
172+
void *userdata) {
173+
struct playlistcontainer_handler *handler = malloc(sizeof (struct playlistcontainer_handler));
174+
handler->request = request;
175+
handler->callback = callback;
176+
handler->playlistcontainer_callbacks = playlistcontainer_callbacks;
177+
handler->userdata = userdata;
178+
sp_playlistcontainer_add_callbacks(pc, handler->playlistcontainer_callbacks,
179+
handler);
180+
return handler;
181+
}
182+
183+
void playlistcontainer_dispatch(sp_playlistcontainer *pc, void *userdata) {
184+
struct playlistcontainer_handler *handler = userdata;
185+
sp_playlistcontainer_remove_callbacks(pc,
186+
handler->playlistcontainer_callbacks,
187+
handler);
188+
handler->callback(pc, handler->request, handler->userdata);
189+
free(handler);
190+
}
191+
156192
static void playlist_state_changed(sp_playlist *playlist, void *userdata) {
157193
if (!sp_playlist_is_loaded(playlist))
158194
return;
@@ -175,6 +211,10 @@ static sp_playlist_callbacks playlist_update_in_progress_callbacks = {
175211
.playlist_update_in_progress = &playlist_update_in_progress
176212
};
177213

214+
static sp_playlistcontainer_callbacks playlistcontainer_loaded_callbacks = {
215+
.container_loaded = &playlistcontainer_dispatch
216+
};
217+
178218
// HTTP handlers
179219

180220
// Standard response handler
@@ -271,6 +311,27 @@ static void inbox_post_complete(sp_inbox *inbox, void *userdata) {
271311
}
272312
}
273313

314+
static void get_user_playlists(sp_playlistcontainer *pc,
315+
struct evhttp_request *request,
316+
void *userdata) {
317+
json_t *json = json_object();
318+
json_t *playlists = json_array();
319+
json_object_set_new(json, "playlists", playlists);
320+
321+
for (int i = 0; i < sp_playlistcontainer_num_playlists(pc); i++) {
322+
sp_playlist *playlist = sp_playlistcontainer_playlist(pc, i);
323+
324+
if (!sp_playlist_is_loaded(playlist)) // TODO(liesen): Wait for it to load?
325+
continue;
326+
327+
json_t *playlist_json = json_object();
328+
playlist_to_json(playlist, playlist_json);
329+
json_array_append_new(playlists, playlist_json);
330+
}
331+
332+
send_reply_json(request, HTTP_OK, "OK", json);
333+
}
334+
274335
static void put_user_inbox(const char *user,
275336
struct evhttp_request *request,
276337
void *userdata) {
@@ -621,6 +682,58 @@ static void put_playlist_patch(sp_playlist *playlist,
621682
&playlist_update_in_progress_callbacks, NULL);
622683
}
623684

685+
static void handle_user_request(struct evhttp_request *request,
686+
char *action,
687+
const char *canonical_username,
688+
sp_session *session) {
689+
if (action == NULL) {
690+
evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request");
691+
return;
692+
}
693+
694+
int http_method = evhttp_request_get_command(request);
695+
696+
switch (http_method) {
697+
case EVHTTP_REQ_GET:
698+
if (strncmp(action, "playlists", 9) == 0) {
699+
sp_playlistcontainer *pc = sp_session_publishedcontainer_for_user_create(
700+
session, canonical_username);
701+
702+
if (sp_playlistcontainer_is_loaded(pc)) {
703+
get_user_playlists(pc, request, session);
704+
} else {
705+
register_playlistcontainer_callbacks(pc, request,
706+
&get_user_playlists,
707+
&playlistcontainer_loaded_callbacks,
708+
session);
709+
}
710+
} else if (strncmp(action, "starred", 7) == 0) {
711+
sp_playlist *playlist = sp_session_starred_for_user_create(session,
712+
canonical_username);
713+
714+
if (sp_playlist_is_loaded(playlist)) {
715+
get_playlist(playlist, request, session);
716+
} else {
717+
register_playlist_callbacks(playlist, request, &get_playlist,
718+
&playlist_state_changed_callbacks,
719+
session);
720+
}
721+
}
722+
break;
723+
724+
case EVHTTP_REQ_PUT:
725+
case EVHTTP_REQ_POST:
726+
if (strncmp(action, "inbox", 5) == 0) {
727+
put_user_inbox(canonical_username, request, session);
728+
}
729+
break;
730+
731+
default:
732+
evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request");
733+
break;
734+
}
735+
}
736+
624737
// Request dispatcher
625738
static void handle_request(struct evhttp_request *request,
626739
void *userdata) {
@@ -656,35 +769,16 @@ static void handle_request(struct evhttp_request *request,
656769

657770
// Handle requests to /user/<user_name>/inbox
658771
if (strncmp(entity, "user", 4) == 0) {
659-
char *user = strtok(NULL, "/");
772+
char *username = strtok(NULL, "/");
660773

661-
if (user == NULL) {
774+
if (username == NULL) {
662775
evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request");
663776
free(uri);
664777
return;
665778
}
666779

667780
char *action = strtok(NULL, "/");
668-
669-
if (action == NULL) {
670-
evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request");
671-
free(uri);
672-
return;
673-
}
674-
675-
switch (http_method) {
676-
case EVHTTP_REQ_PUT:
677-
case EVHTTP_REQ_POST:
678-
if (strncmp(action, "inbox", 5) == 0) {
679-
put_user_inbox(user, request, session);
680-
}
681-
break;
682-
683-
default:
684-
evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request");
685-
break;
686-
}
687-
781+
handle_user_request(request, username, action, session);
688782
free(uri);
689783
return;
690784
}

0 commit comments

Comments
 (0)