1
0
mirror of https://github.com/SuperBFG7/ympd synced 2024-12-28 11:50:26 +00:00

Output json with frozen

This commit is contained in:
jcorporation 2018-06-17 23:42:22 +01:00
parent 3df104e72d
commit 4dcf613708
5 changed files with 79 additions and 100 deletions

View File

@ -7,13 +7,13 @@ set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_PACKAGE_VERSION_PATCH "0") set(CPACK_PACKAGE_VERSION_PATCH "0")
if(CMAKE_BUILD_TYPE MATCHES RELEASE) if(CMAKE_BUILD_TYPE MATCHES RELEASE)
set(ASSETS_PATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/htdocs") set(ASSETS_PATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/htdocs")
set(DEBUG "OFF")
else() else()
set(ASSETS_PATH "${PROJECT_SOURCE_DIR}/htdocs") set(ASSETS_PATH "${PROJECT_SOURCE_DIR}/htdocs")
set(DEBUG ON) set(DEBUG "ON")
endif() endif()
option(WITH_IPV6 "enable IPv6 support" ON) option(WITH_IPV6 "enable IPv6 support" ON)
option(WITH_SSL "enable SSL support" ON)
find_package(LibMPDClient REQUIRED) find_package(LibMPDClient REQUIRED)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
@ -23,17 +23,11 @@ include_directories(${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} ${LIBMPDCLIENT_I
include(CheckCSourceCompiles) include(CheckCSourceCompiles)
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic ")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic -D_FORTIFY_SOURCE=2 -fstack-protector -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=shift -fsanitize=integer-divide-by-zero -fsanitize=unreachable -fsanitize=vla-bound -fsanitize=null -fsanitize=return -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=bounds-strict -fsanitize=alignment -fsanitize=object-size -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=nonnull-attribute -fsanitize=returns-nonnull-attribute -fsanitize=bool -fsanitize=enum -fsanitize=vptr -static-libasan") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -D_FORTIFY_SOURCE=2 -fstack-protector -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=shift -fsanitize=integer-divide-by-zero -fsanitize=unreachable -fsanitize=vla-bound -fsanitize=null -fsanitize=return -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=bounds-strict -fsanitize=alignment -fsanitize=object-size -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=nonnull-attribute -fsanitize=returns-nonnull-attribute -fsanitize=bool -fsanitize=enum -fsanitize=vptr -static-libasan")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb")
if(WITH_IPV6) if(WITH_IPV6)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_IPV6) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_IPV6)
endif() endif()
if(WITH_SSL)
find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_SSL)
endif()
file(GLOB RESOURCES file(GLOB RESOURCES
RELATIVE ${PROJECT_SOURCE_DIR} RELATIVE ${PROJECT_SOURCE_DIR}
@ -54,7 +48,7 @@ set(SOURCES
) )
add_executable(mympd ${SOURCES}) add_executable(mympd ${SOURCES})
target_link_libraries(mympd ${LIBMPDCLIENT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}) target_link_libraries(mympd ${LIBMPDCLIENT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS mympd DESTINATION bin) install(TARGETS mympd DESTINATION bin)
install(FILES mympd.1 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) install(FILES mympd.1 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1)

View File

@ -27,12 +27,11 @@ Dependencies
------------ ------------
- libmpdclient 2: http://www.musicpd.org/libs/libmpdclient/ - libmpdclient 2: http://www.musicpd.org/libs/libmpdclient/
- cmake 2.6: http://cmake.org/ - cmake 2.6: http://cmake.org/
- OpenSSL: https://www.openssl.org/
Unix Build Instructions Unix Build Instructions
----------------------- -----------------------
1. install dependencies. cmake, libmpdclient (dev), and OpenSSL (dev) are available from all major distributions. 1. install dependencies. cmake and libmpdclient (dev) are available from all major distributions.
2. create build directory ```cd /path/to/src; mkdir build; cd build``` 2. create build directory ```cd /path/to/src; mkdir build; cd build```
3. create makefile ```cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE=RELEASE``` 3. create makefile ```cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE=RELEASE```
4. build ```make``` 4. build ```make```
@ -56,20 +55,6 @@ Usage: ./mympd [OPTION]...
--help this help --help this help
``` ```
SSL Support
-----------
To run myMPD with SSL support:
- create a certificate (key and cert in the same file), example:
```
# openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 1000 -nodes -sha256
# cat key.pem cert.pem > ssl.pem
```
- tell myMPD to use a webport using SSL and where to find the certificate:
```
# ./mympd -w "ssl://8081:/path/to/ssl.pem"
```
Copyright Copyright
--------- ---------
ympd: 2013-2014 <andy@ndyk.de> ympd: 2013-2014 <andy@ndyk.de>

View File

@ -754,9 +754,10 @@ int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsi
{ {
struct mpd_status *status; struct mpd_status *status;
const struct mpd_audio_format *audioformat; const struct mpd_audio_format *audioformat;
struct mpd_output *out; struct mpd_output *output;
char *cur = buffer; int len;
const char *end = buffer + MAX_SIZE; int nr;
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
status = mpd_run_status(mpd.conn); status = mpd_run_status(mpd.conn);
if (!status) { if (!status) {
@ -768,78 +769,73 @@ int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsi
audioformat = mpd_status_get_audio_format(status); audioformat = mpd_status_get_audio_format(status);
} }
cur += json_emit_raw_str(cur, end - cur, "{\"type\": \"state\", \"data\":{\"state\":"); len = json_printf(&out,"{type:state, data:{"
cur += json_emit_int(cur, end - cur, mpd_status_get_state(status)); "state:%d, volume:%d, songpos: %d, elapsedTime: %d, "
cur += json_emit_raw_str(cur, end - cur, ",\"volume\":"); "totalTime:%d, currentsongid: %d, kbitrate: %d, "
cur += json_emit_int(cur, end - cur, mpd_status_get_volume(status)); "audioformat: { sample_rate: %d, bits: %d, channels: %d}, "
cur += json_emit_raw_str(cur, end - cur, ",\"songpos\":"); "queue_length: %d, nextsongpos: %d, nextsongid: %d, "
cur += json_emit_int(cur, end - cur, mpd_status_get_song_pos(status)); "queue_version: %d",
cur += json_emit_raw_str(cur, end - cur, ",\"elapsedTime\":"); mpd_status_get_state(status),
cur += json_emit_int(cur, end - cur, mpd_status_get_elapsed_time(status)); mpd_status_get_volume(status),
cur += json_emit_raw_str(cur, end - cur, ",\"totalTime\":"); mpd_status_get_song_pos(status),
cur += json_emit_int(cur, end - cur, mpd_status_get_total_time(status)); mpd_status_get_elapsed_time(status),
cur += json_emit_raw_str(cur, end - cur, ",\"currentsongid\":"); mpd_status_get_total_time(status),
cur += json_emit_int(cur, end - cur, mpd_status_get_song_id(status)); mpd_status_get_song_id(status),
cur += json_emit_raw_str(cur, end - cur, ",\"kbitrate\":"); mpd_status_get_kbit_rate(status),
cur += json_emit_int(cur, end - cur, mpd_status_get_kbit_rate(status)); audioformat ? audioformat->sample_rate : 0,
cur += json_emit_raw_str(cur, end - cur, ",\"audioformat\": {"); audioformat ? audioformat->bits : 0,
cur += json_emit_raw_str(cur, end - cur, "\"sample_rate\":"); audioformat ? audioformat->channels : 0,
cur += json_emit_int(cur, end - cur, audioformat ? audioformat->sample_rate : 0); mpd_status_get_queue_length(status),
cur += json_emit_raw_str(cur, end - cur, ",\"bits\":"); mpd_status_get_next_song_pos(status),
cur += json_emit_int(cur, end - cur, audioformat ? audioformat->bits : 0); mpd_status_get_next_song_id(status),
cur += json_emit_raw_str(cur, end - cur, ",\"channels\":"); mpd_status_get_queue_version(status)
cur += json_emit_int(cur, end - cur, audioformat ? audioformat->channels : 0); );
cur += json_emit_raw_str(cur, end - cur, "},\"queue_length\":");
cur += json_emit_int(cur, end - cur, mpd_status_get_queue_length(status)); len += json_printf(&out, ",outputs: {");
cur += json_emit_raw_str(cur, end - cur, ",\"nextsongpos\":");
cur += json_emit_int(cur, end - cur, mpd_status_get_next_song_pos(status));
cur += json_emit_raw_str(cur, end - cur, ",\"nextsongid\":");
cur += json_emit_int(cur, end - cur, mpd_status_get_next_song_id(status));
cur += json_emit_raw_str(cur, end - cur, ",\"queue_version\":");
cur += json_emit_int(cur, end - cur, mpd_status_get_queue_version(status));
cur += json_emit_raw_str(cur, end - cur, ",\"outputs\": {");
mpd_send_outputs(mpd.conn); mpd_send_outputs(mpd.conn);
while ((out = mpd_recv_output(mpd.conn)) != NULL) { nr=0;
cur += json_emit_raw_str(cur, end - cur, "\""); while ((output = mpd_recv_output(mpd.conn)) != NULL) {
cur += json_emit_int(cur, end - cur, mpd_output_get_id(out)); if (nr++) len += json_printf(&out, ",");
cur += json_emit_raw_str(cur, end - cur, "\":"); len += json_printf(&out, "\"%d\":%d",
cur += json_emit_int(cur, end - cur, mpd_output_get_enabled(out)); mpd_output_get_id(output),
cur += json_emit_raw_str(cur, end - cur, ","); mpd_output_get_enabled(output)
mpd_output_free(out); );
mpd_output_free(output);
} }
if (!mpd_response_finish(mpd.conn)) { if (!mpd_response_finish(mpd.conn)) {
fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn)); fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn));
mpd_connection_clear_error(mpd.conn); mpd_connection_clear_error(mpd.conn);
} }
cur --; len += json_printf(&out, "}}}");
cur += json_emit_raw_str(cur, end - cur, "}}}");
*current_song_id = mpd_status_get_song_id(status); *current_song_id = mpd_status_get_song_id(status);
*next_song_id = mpd_status_get_next_song_id(status); *next_song_id = mpd_status_get_next_song_id(status);
*queue_version = mpd_status_get_queue_version(status); *queue_version = mpd_status_get_queue_version(status);
mpd_status_free(status); mpd_status_free(status);
return cur - buffer;
if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n");
return len;
} }
int mympd_put_welcome(char *buffer) int mympd_put_welcome(char *buffer)
{ {
int len; int len;
len = snprintf(buffer, MAX_SIZE, struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
"{\"type\":\"welcome\", \"data\":{"
"\"version\":\"%s\"}}",
MYMPD_VERSION
);
len = json_printf(&out, "{type: %Q, data: { version: %Q}}", "welcome", MYMPD_VERSION);
if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n");
return len; return len;
} }
int mympd_put_settings(char *buffer) int mympd_put_settings(char *buffer)
{ {
struct mpd_status *status; struct mpd_status *status;
int len;
char *replaygain; char *replaygain;
int len;
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
status = mpd_run_status(mpd.conn); status = mpd_run_status(mpd.conn);
if (!status) { if (!status) {
@ -855,11 +851,11 @@ int mympd_put_settings(char *buffer)
mpd_return_pair(mpd.conn, pair); mpd_return_pair(mpd.conn, pair);
} }
len = snprintf(buffer, MAX_SIZE, len = json_printf(&out,
"{\"type\":\"settings\", \"data\":{" "{type:settings, data:{"
"\"repeat\":%d, \"single\":%d, \"crossfade\":%d, \"consume\":%d, \"random\":%d, " "repeat:%d, single:%d, crossfade:%d, consume:%d, random:%d, "
"\"mixrampdb\": %f, \"mixrampdelay\": %f, \"mpdhost\" : \"%s\", \"mpdport\": \"%d\", \"passwort_set\": %s, " "mixrampdb: %f, mixrampdelay: %f, mpdhost : %Q, mpdport: %d, passwort_set: %B, "
"\"streamport\": \"%d\",\"coverimage\": \"%s\", \"max_elements_per_page\": %d, \"replaygain\": \"%s\"" "streamport: %d, coverimage: %Q, max_elements_per_page: %d, replaygain: %Q"
"}}", "}}",
mpd_status_get_repeat(status), mpd_status_get_repeat(status),
mpd_status_get_single(status), mpd_status_get_single(status),
@ -875,37 +871,40 @@ int mympd_put_settings(char *buffer)
replaygain replaygain
); );
mpd_status_free(status); mpd_status_free(status);
if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n");
return len; return len;
} }
int mympd_put_outputnames(char *buffer) int mympd_put_outputnames(char *buffer)
{ {
char *cur = buffer; struct mpd_output *output;
const char *end = buffer + MAX_SIZE; int len;
struct mpd_output *out; int nr;
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
cur += json_emit_raw_str(cur, end - cur, "{\"type\": \"outputnames\", \"data\":{"); len = json_printf(&out,"{type: outputnames, data:{");
mpd_send_outputs(mpd.conn); mpd_send_outputs(mpd.conn);
nr=0;
while ((out = mpd_recv_output(mpd.conn)) != NULL) { while ((output = mpd_recv_output(mpd.conn)) != NULL) {
cur += json_emit_raw_str(cur, end - cur, "\""); if (nr++) len += json_printf(&out, ",");
cur += json_emit_int(cur, end - cur, mpd_output_get_id(out)); len += json_printf(&out,"\"%d\":%Q",
cur += json_emit_raw_str(cur, end - cur, "\":"); mpd_output_get_id(output),
cur += json_emit_quoted_str(cur, end - cur, mpd_output_get_name(out)); mpd_output_get_name(output)
cur += json_emit_raw_str(cur, end - cur, ","); );
mpd_output_free(out); mpd_output_free(output);
} }
if (!mpd_response_finish(mpd.conn)) { if (!mpd_response_finish(mpd.conn)) {
fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn)); fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn));
mpd_connection_clear_error(mpd.conn); mpd_connection_clear_error(mpd.conn);
} }
cur --; len += json_printf(&out,"}}");
cur += json_emit_raw_str(cur, end - cur, "}}");
return cur - buffer; if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n");
return len;
} }
int mympd_put_current_song(char *buffer) int mympd_put_current_song(char *buffer)

View File

@ -132,6 +132,7 @@ struct t_mpd_client_session {
}; };
void mympd_poll(struct mg_mgr *s); void mympd_poll(struct mg_mgr *s);
void callback_mympd_jsonrpc(struct mg_connection *nc, const struct mg_str msg);
void callback_mympd(struct mg_connection *nc, const struct mg_str msg); void callback_mympd(struct mg_connection *nc, const struct mg_str msg);
int mympd_close_handler(struct mg_connection *c); int mympd_close_handler(struct mg_connection *c);
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigned *queue_version); int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigned *queue_version);

View File

@ -142,7 +142,7 @@ int main(int argc, char **argv)
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
while((n = getopt_long(argc, argv, "D:h:p:w:u:vm:s:i:", while((n = getopt_long(argc, argv, "D:h:p:w:u:vm:s:i:c:",
long_options, &option_index)) != -1) { long_options, &option_index)) != -1) {
switch (n) { switch (n) {
case 'D': case 'D':
@ -203,7 +203,7 @@ int main(int argc, char **argv)
nc = mg_bind(&mgr, webport, ev_handler); nc = mg_bind(&mgr, webport, ev_handler);
if (nc == NULL) { if (nc == NULL) {
printf("myMPD can't bind to port %s\n", webport); fprintf(stderr, "Error starting server on port %s\n", webport);
return EXIT_FAILURE; return EXIT_FAILURE;
} }