From 31f1df974ca707b98f4ae92803fe2ca117a0321a Mon Sep 17 00:00:00 2001 From: Andrew Karpow Date: Wed, 8 Jan 2014 02:23:02 +0100 Subject: [PATCH] fix for firefox, large datasets via http instead websockets --- htdocs/js/mpd.js | 14 +++++++------- src/http_server.c | 23 +++++++++++++++-------- src/http_server.h | 6 +++++- src/mpd_client.c | 43 ++++++++++++++++++------------------------- src/mpd_client.h | 8 ++++++++ src/ympd.c | 16 +++++++++++++--- 6 files changed, 66 insertions(+), 44 deletions(-) diff --git a/htdocs/js/mpd.js b/htdocs/js/mpd.js index 8f66e88..f343033 100644 --- a/htdocs/js/mpd.js +++ b/htdocs/js/mpd.js @@ -17,10 +17,10 @@ var app = $.sammy(function() { current_app = 'playlist'; $('#breadcrump').addClass('hide'); $('#salamisandwich').find("tr:gt(0)").remove(); - if(is_firefox) + //if(is_firefox) $.get( "/api/get_playlist", socket.onmessage); - else - socket.send("MPD_API_GET_PLAYLIST"); + //else + // socket.send("MPD_API_GET_PLAYLIST"); $('#panel-heading').text("Playlist"); $('#playlist').addClass('active'); @@ -34,10 +34,10 @@ var app = $.sammy(function() { if(path == '') path = "/"; - if(is_firefox) + //if(is_firefox) $.get( "/api/get_browse/" + encodeURIComponent(path), socket.onmessage); - else - socket.send("MPD_API_GET_BROWSE,"+path); + //else + // socket.send("MPD_API_GET_BROWSE,"+path); $('#panel-heading').text("Browse database: "+path+""); var path_array = path[0].split('/'); @@ -228,6 +228,7 @@ function webSocketConnect() { socket.send("MPD_API_GET_TRACK_INFO"); $('#alert').addClass("hide"); + last_state = obj; break; case "disconnected": $('#alert') @@ -246,7 +247,6 @@ function webSocketConnect() { break; } - last_state = obj; } socket.onclose = function(){ diff --git a/src/http_server.c b/src/http_server.c index 15df26f..ccd1fa2 100644 --- a/src/http_server.c +++ b/src/http_server.c @@ -3,9 +3,11 @@ #include #include #include +#include #include "http_server.h" #include "mpd_client.h" +#include "config.h" char *resource_path = LOCAL_RESOURCE_PATH; @@ -80,14 +82,14 @@ int callback_http(struct libwebsocket_context *context, case LWS_CALLBACK_HTTP: if(in && strncmp((const char *)in, "/api/", 5) == 0) { - response_buffer = (char *)malloc(100 * 1024 + 100); + response_buffer = (char *)malloc(MAX_SIZE + 100); p = response_buffer; /* put content length and payload to buffer */ if(strncmp((const char *)in, "/api/get_browse", 15) == 0) { char *url; - if(sscanf(in, "/api/get_browse/%m[^\t\n]", &url)) + if(sscanf(in, "/api/get_browse/%m[^\t\n]", &url) && url) { char *url_decoded = url_decode(url); printf("searching for %s", url_decoded); @@ -101,6 +103,15 @@ int callback_http(struct libwebsocket_context *context, } else if(strncmp((const char *)in, "/api/get_playlist", 17) == 0) response_size = mpd_put_playlist(response_buffer + 98); + else if(strncmp((const char *)in, "/api/version", 17) == 0) + response_size = snprintf(response_buffer, MAX_SIZE, + "{\"type\":\"version\",\"data\":{" + "\"ympd_version\":\"%d.%d.%d\"," + "\"mpd_version\":\"%d.%d.%d\"" + "}}", + YMPD_VERSION_MAJOR, YMPD_VERSION_MINOR, YMPD_VERSION_PATCH, + LIBMPDCLIENT_MAJOR_VERSION, LIBMPDCLIENT_MINOR_VERSION, + LIBMPDCLIENT_PATCH_VERSION); else { /* invalid request, close connection */ @@ -114,7 +125,7 @@ int callback_http(struct libwebsocket_context *context, response_size ); response_buffer[98] = '{'; - + n = libwebsocket_write(wsi, (unsigned char *)response_buffer, p - response_buffer, LWS_WRITE_HTTP); @@ -124,10 +135,6 @@ int callback_http(struct libwebsocket_context *context, */ libwebsocket_callback_on_writable(context, wsi); - } - else if(in && strcmp((const char *)in, "getPlaylist") == 0) - { - } else { @@ -138,7 +145,7 @@ int callback_http(struct libwebsocket_context *context, } sprintf(buf, "%s%s", resource_path, whitelist[n].urlpath); - if (libwebsockets_serve_http_file(context, wsi, buf, whitelist[n].mimetype)) + if (libwebsockets_serve_http_file(context, wsi, buf, whitelist[n].mimetype, NULL)) return -1; /* through completion or error, close the socket */ } break; diff --git a/src/http_server.h b/src/http_server.h index 9f899b6..d98d512 100644 --- a/src/http_server.h +++ b/src/http_server.h @@ -1,3 +1,6 @@ +#ifndef __HTTP_SERVER_H__ +#define __HTTP_SERVER_H__ + #include struct per_session_data__http { @@ -8,4 +11,5 @@ int callback_http(struct libwebsocket_context *context, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len); -#define LOCAL_RESOURCE_PATH DATADIR"/htdocs" +#endif + diff --git a/src/mpd_client.c b/src/mpd_client.c index c7eec25..b38a9a2 100644 --- a/src/mpd_client.c +++ b/src/mpd_client.c @@ -1,3 +1,8 @@ +#include +#include +#include +#include +#include #include #include @@ -6,33 +11,19 @@ #include #include -#include -#include -#include -#include -#include - #include "mpd_client.h" -#define MAX_SIZE 1024 * 100 - struct mpd_connection *conn = NULL; enum mpd_conn_states mpd_conn_state = MPD_DISCONNECTED; enum mpd_state mpd_play_state = MPD_STATE_UNKNOWN; unsigned queue_version; -void *mpd_idle_connection(void *_data) -{ - -} - int callback_ympd(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { - size_t n; - int m; + size_t n, m = -1; char *buf = NULL, *p; struct per_session_data__ympd *pss = (struct per_session_data__ympd *)user; @@ -53,7 +44,8 @@ int callback_ympd(struct libwebsocket_context *context, if(mpd_conn_state != MPD_CONNECTED) { n = snprintf(p, MAX_SIZE, "{\"type\":\"disconnected\"}"); } - else if((pss->queue_version != queue_version) || (pss->do_send & DO_SEND_PLAYLIST)) { + //else if((pss->queue_version != queue_version) || (pss->do_send & DO_SEND_PLAYLIST)) { + else if(pss->do_send & DO_SEND_PLAYLIST) { n = mpd_put_playlist(p); pss->queue_version = queue_version; pss->do_send &= ~DO_SEND_PLAYLIST; @@ -107,32 +99,32 @@ int callback_ympd(struct libwebsocket_context *context, } else if(!strncmp((const char *)in, MPD_API_RM_TRACK, sizeof(MPD_API_RM_TRACK)-1)) { unsigned id; - if(sscanf(in, "MPD_API_RM_TRACK,%d", &id)) + if(sscanf(in, "MPD_API_RM_TRACK,%u", &id)) mpd_run_delete_id(conn, id); } else if(!strncmp((const char *)in, MPD_API_PLAY_TRACK, sizeof(MPD_API_PLAY_TRACK)-1)) { unsigned id; - if(sscanf(in, "MPD_API_PLAY_TRACK,%d", &id)) + if(sscanf(in, "MPD_API_PLAY_TRACK,%u", &id)) mpd_run_play_id(conn, id); } else if(!strncmp((const char *)in, MPD_API_TOGGLE_RANDOM, sizeof(MPD_API_TOGGLE_RANDOM)-1)) { unsigned random; - if(sscanf(in, "MPD_API_TOGGLE_RANDOM,%d", &random)) + if(sscanf(in, "MPD_API_TOGGLE_RANDOM,%u", &random)) mpd_run_random(conn, random); } else if(!strncmp((const char *)in, MPD_API_TOGGLE_REPEAT, sizeof(MPD_API_TOGGLE_REPEAT)-1)) { unsigned repeat; - if(sscanf(in, "MPD_API_TOGGLE_REPEAT,%d", &repeat)) + if(sscanf(in, "MPD_API_TOGGLE_REPEAT,%u", &repeat)) mpd_run_repeat(conn, repeat); } else if(!strncmp((const char *)in, MPD_API_TOGGLE_CONSUME, sizeof(MPD_API_TOGGLE_CONSUME)-1)) { unsigned consume; - if(sscanf(in, "MPD_API_TOGGLE_CONSUME,%d", &consume)) + if(sscanf(in, "MPD_API_TOGGLE_CONSUME,%u", &consume)) mpd_run_consume(conn, consume); } else if(!strncmp((const char *)in, MPD_API_TOGGLE_SINGLE, sizeof(MPD_API_TOGGLE_SINGLE)-1)) { unsigned single; - if(sscanf(in, "MPD_API_TOGGLE_SINGLE,%d", &single)) + if(sscanf(in, "MPD_API_TOGGLE_SINGLE,%u", &single)) mpd_run_single(conn, single); } else if(!strncmp((const char *)in, MPD_API_SET_VOLUME, sizeof(MPD_API_SET_VOLUME)-1)) { @@ -168,7 +160,8 @@ void mpd_loop() switch (mpd_conn_state) { case MPD_DISCONNECTED: /* Try to connect */ - conn = mpd_connection_new("127.0.0.1", 6600, 3000); + lwsl_notice("MPD Connecting to %s:%d\n", mpd_host, mpd_port); + conn = mpd_connection_new(mpd_host, mpd_port, 3000); if (conn == NULL) { lwsl_err("Out of memory."); mpd_conn_state = MPD_FAILURE; @@ -176,7 +169,7 @@ void mpd_loop() } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) { - lwsl_notice("MPD connection: %s\n", mpd_connection_get_error_message(conn)); + lwsl_err("MPD connection: %s\n", mpd_connection_get_error_message(conn)); mpd_conn_state = MPD_FAILURE; return; } @@ -186,7 +179,7 @@ void mpd_loop() break; case MPD_FAILURE: - lwsl_notice("MPD connection failed.\n"); + lwsl_err("MPD connection failed.\n"); if(conn != NULL) mpd_connection_free(conn); diff --git a/src/mpd_client.h b/src/mpd_client.h index 7b88bd9..9320209 100644 --- a/src/mpd_client.h +++ b/src/mpd_client.h @@ -1,5 +1,10 @@ +#ifndef __MPD_CLIENT_H__ +#define __MPD_CLIENT_H__ + #include +#define MAX_SIZE 1024 * 100 + #define DO_SEND_STATE (1 << 0) #define DO_SEND_PLAYLIST (1 << 1) #define DO_SEND_TRACK_INFO (1 << 2) @@ -51,3 +56,6 @@ int mpd_put_browse(char *buffer, char *path); int mpd_port; const char *mpd_host; + +#endif + diff --git a/src/ympd.c b/src/ympd.c index da9b198..275bc33 100644 --- a/src/ympd.c +++ b/src/ympd.c @@ -8,6 +8,7 @@ #include "http_server.h" #include "mpd_client.h" +#include "config.h" extern char *optarg; extern char *resource_path; @@ -19,7 +20,6 @@ struct libwebsocket_protocols protocols[] = { callback_http, /* callback */ sizeof (struct per_session_data__http), /* per_session_data_size */ 0, /* max frame size / rx buffer */ - 0, /* no_buffer_all_partial_tx */ }, { "ympd-client", @@ -68,11 +68,12 @@ int main(int argc, char **argv) {"gid", required_argument, 0, 'g'}, {"uid", required_argument, 0, 'u'}, {"verbose", optional_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 0 }, {0, 0, 0, 0 } }; - while((n = getopt_long(argc, argv, "h:p:i:w:r:c:k:g:u:v::", + while((n = getopt_long(argc, argv, "h:p:i:w:r:c:k:g:u:v::V", long_options, &option_index)) != -1) { switch (n) { case 'h': @@ -108,6 +109,14 @@ int main(int argc, char **argv) lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO, NULL); break; + case 'V': + fprintf(stdout, "ympd %d.%d.%d\n" + "Copyright (C) 2014 Andrew Karpow \n" + "Resource Path: "LOCAL_RESOURCE_PATH"\n" + "built " __DATE__ " "__TIME__ " ("__VERSION__")\n", + YMPD_VERSION_MAJOR, YMPD_VERSION_MINOR, YMPD_VERSION_PATCH); + return EXIT_SUCCESS; + break; default: fprintf(stderr, "Usage: %s [OPTION]...\n\n" "\t-h, --host \t\tconnect to mpd at host [localhost]\n" @@ -119,7 +128,8 @@ int main(int argc, char **argv) "\t-k, --ssl_key \tssl private key filepath\n" "\t-u, --uid \t\t\tuser-id after socket bind\n" "\t-g, --gid \t\t\tgroup-id after socket bind\n" - "\t-v, --verbose[]\t\tverbosity level\n" + "\t-v, --verbose[]\t\tverbosity level\n" + "\t-V, --version\t\t\tget version\n" "\t--help\t\t\t\tthis help\n" , argv[0]); return EXIT_FAILURE;