From 3df104e72d63f2ec53de983aa5ce5824fdb03af8 Mon Sep 17 00:00:00 2001 From: jcorporation Date: Thu, 14 Jun 2018 23:57:57 +0100 Subject: [PATCH] First code for new jsonrpc api --- CMakeLists.txt | 1 + htdocs/js/mpd.js | 3 ++- src/mpd_client.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mympd.c | 12 +++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4672deb..b4a0985 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ set(SOURCES src/mpd_client.c src/mongoose/mongoose.c src/frozen/frozen.c + src/json_encode.c ) add_executable(mympd ${SOURCES}) diff --git a/htdocs/js/mpd.js b/htdocs/js/mpd.js index 2828e90..8f66ea2 100644 --- a/htdocs/js/mpd.js +++ b/htdocs/js/mpd.js @@ -856,7 +856,8 @@ function parseListDBtags(obj) { ' '+ ''; $('#BrowseDatabaseAlbumCards').append(card); - $.ajax({url: "/api", mimeType: "text/plain", contentType:"text/plain", method: "POST", data: "MPD_API_GET_ARTISTALBUMTITLES," + obj.searchstr + ","+obj.data[item].value}).done(function( data ) { + $.ajax({url: "/jsonrpc", contentType:"application/json", method: "POST", + data: JSON.stringify({"cmd":"MPD_API_GET_ARTISTALBUMTITLES", "data": { "albumartist": obj.searchstr, "album": obj.data[item].value}})}).done(function( data ) { var obj = JSON.parse(data); parseListTitles(obj); }); diff --git a/src/mpd_client.c b/src/mpd_client.c index e5510aa..d015922 100644 --- a/src/mpd_client.c +++ b/src/mpd_client.c @@ -60,6 +60,59 @@ static inline enum mpd_cmd_ids get_cmd_id(const char *cmd) return -1; } +void callback_mympd_jsonrpc(struct mg_connection *nc, const struct mg_str msg) +{ + size_t n = 0; + char *cmd; + int int_buf; + int je; + float float_buf; + char *p_charbuf1; + char *p_charbuf2; + char *p_charbuf3; + + #ifdef DEBUG + fprintf(stdout,"Got request: %s\n",msg.p); + #endif + + json_scanf(msg.p, msg.len, "{cmd:%Q}", &cmd); + enum mpd_cmd_ids cmd_id = get_cmd_id(cmd); + + if(cmd_id == -1) + return; + + switch(cmd_id) { + case MPD_API_GET_ARTISTALBUMTITLES: + je = json_scanf(msg.p, msg.len, "{ data: { albumartist:%Q, album:%Q } }", &p_charbuf1, &p_charbuf2); + if (je == 2) + n = mympd_put_songs_in_album(mpd.buf, p_charbuf1, p_charbuf2); + free(p_charbuf1); + free(p_charbuf2); + break; + } + free(cmd); + + if(mpd.conn_state == MPD_CONNECTED && mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) + { + #ifdef DEBUG + fprintf(stdout,"Error: %s\n",mpd_connection_get_error_message(mpd.conn)); + #endif + n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"error\", \"data\": \"%s\"}", + mpd_connection_get_error_message(mpd.conn)); + + /* Try to recover error */ + if (!mpd_connection_clear_error(mpd.conn)) + mpd.conn_state = MPD_FAILURE; + } + + if(n > 0) { + #ifdef DEBUG + fprintf(stdout,"Send http response:\n %s\n",mpd.buf); + #endif + mg_send_http_chunk(nc, mpd.buf, n); + } +} + void callback_mympd(struct mg_connection *nc, const struct mg_str msg) { enum mpd_cmd_ids cmd_id = get_cmd_id(msg.p); diff --git a/src/mympd.c b/src/mympd.c index f585907..72deb5b 100644 --- a/src/mympd.c +++ b/src/mympd.c @@ -52,6 +52,15 @@ static void handle_api(struct mg_connection *nc, struct http_message *hm) { mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */ } +static void handle_jsonrpc(struct mg_connection *nc, struct http_message *hm) { + mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); + char buf[1000] = {0}; + memcpy(buf, hm->body.p,sizeof(buf) - 1 < hm->body.len ? sizeof(buf) - 1 : hm->body.len); + struct mg_str d = {buf, strlen(buf)}; + callback_mympd_jsonrpc(nc, d); + mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */ +} + static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { switch(ev) { case MG_EV_WEBSOCKET_HANDSHAKE_DONE: { @@ -80,6 +89,9 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { if (mg_vcmp(&hm->uri, "/api") == 0) { handle_api(nc, hm); } + else if (mg_vcmp(&hm->uri, "/jsonrpc") == 0) { + handle_jsonrpc(nc, hm); + } else { mg_serve_http(nc, hm, s_http_server_opts); }