mirror of
https://github.com/SuperBFG7/ympd
synced 2024-11-05 22:36:16 +00:00
Fix: improve processing of mpd idle events
This commit is contained in:
parent
17509b50da
commit
b9a5c00956
@ -689,6 +689,7 @@ function webSocketConnect() {
|
||||
break;
|
||||
case 'error':
|
||||
showNotification(obj.data, '', '', 'danger');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
162
src/mpd_client.c
162
src/mpd_client.c
@ -48,6 +48,8 @@ static inline enum mpd_cmd_ids get_cmd_id(const char *cmd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
enum mpd_idle idle_bitmask_save = 0;
|
||||
|
||||
void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
size_t n = 0;
|
||||
char *cmd;
|
||||
@ -57,9 +59,11 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
char *p_charbuf1, *p_charbuf2, *p_charbuf3;
|
||||
struct mympd_state { int a; int b; } state = { .a = 0, .b = 0 };
|
||||
enum mpd_cmd_ids cmd_id;
|
||||
struct pollfd fds[1];
|
||||
int pollrc;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout,"Got request: %s\n",msg.p);
|
||||
fprintf(stdout,"Got request: %s\n", msg.p);
|
||||
#endif
|
||||
|
||||
je = json_scanf(msg.p, msg.len, "{cmd: %Q}", &cmd);
|
||||
@ -72,8 +76,22 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
cmd_id = get_cmd_id("MPD_API_UNKNOWN");
|
||||
|
||||
mpd_send_noidle(mpd.conn);
|
||||
//save idle events (processing later)
|
||||
fds[0].fd = mpd_connection_get_fd(mpd.conn);
|
||||
fds[0].events = POLLIN;
|
||||
pollrc = poll(fds, 1, 100);
|
||||
if (pollrc > 0) {
|
||||
idle_bitmask_save = mpd_recv_idle(mpd.conn, false);
|
||||
#ifdef DEBUG
|
||||
if (idle_bitmask_save > 0)
|
||||
fprintf(stderr, "IDLE EVENT BEFORE REQUEST: %d\n", idle_bitmask_save);
|
||||
#endif
|
||||
}
|
||||
mpd_response_finish(mpd.conn);
|
||||
|
||||
//handle request
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "HANDLE REQUEST: %s\n", cmd);
|
||||
#endif
|
||||
switch(cmd_id) {
|
||||
case MPD_API_UNKNOWN:
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Unknown request\"}");
|
||||
@ -503,7 +521,7 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Send http response:\n %s\n", mpd.buf);
|
||||
//fprintf(stdout, "Send http response:\n %s\n", mpd.buf);
|
||||
#endif
|
||||
mg_send_http_chunk(nc, mpd.buf, n);
|
||||
}
|
||||
@ -521,6 +539,65 @@ void mympd_notify(struct mg_mgr *s) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void mympd_parse_idle(struct mg_mgr *s, enum mpd_idle idle_bitmask) {
|
||||
int len = 0;
|
||||
for (unsigned j = 0;; j ++) {
|
||||
enum mpd_idle idle_event = 1 << j;
|
||||
const char *idle_name = mpd_idle_name(idle_event);
|
||||
if (idle_name == NULL)
|
||||
break;
|
||||
if (idle_bitmask & idle_event) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "IDLE: %s\n", idle_name);
|
||||
#endif
|
||||
switch(idle_event) {
|
||||
case MPD_IDLE_DATABASE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_database\"}");
|
||||
break;
|
||||
case MPD_IDLE_STORED_PLAYLIST:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_stored_playlist\"}");
|
||||
break;
|
||||
case MPD_IDLE_QUEUE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_queue\"}");
|
||||
break;
|
||||
case MPD_IDLE_PLAYER:
|
||||
len = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version, &mpd.queue_length);
|
||||
if (config.stickers) {
|
||||
mympd_count_song_id(mpd.song_id, "playCount", 1);
|
||||
mympd_last_played_song_id(mpd.song_id);
|
||||
}
|
||||
break;
|
||||
case MPD_IDLE_MIXER:
|
||||
len = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version, &mpd.queue_length);
|
||||
break;
|
||||
case MPD_IDLE_OUTPUT:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_outputs\"}");
|
||||
break;
|
||||
case MPD_IDLE_OPTIONS:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_options\"}");
|
||||
break;
|
||||
case MPD_IDLE_UPDATE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_update\"}");
|
||||
break;
|
||||
case MPD_IDLE_STICKER:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_sticker\"}");
|
||||
break;
|
||||
case MPD_IDLE_SUBSCRIPTION:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_subscription\"}");
|
||||
break;
|
||||
case MPD_IDLE_MESSAGE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_message\"}");
|
||||
break;
|
||||
default:
|
||||
len = 0;
|
||||
}
|
||||
if (len > 0)
|
||||
mympd_notify(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mympd_idle(struct mg_mgr *s, int timeout) {
|
||||
struct pollfd fds[1];
|
||||
int pollrc;
|
||||
@ -577,9 +654,24 @@ void mympd_idle(struct mg_mgr *s, int timeout) {
|
||||
fds[0].fd = mpd_connection_get_fd(mpd.conn);
|
||||
fds[0].events = POLLIN;
|
||||
pollrc = poll(fds, 1, timeout);
|
||||
if (pollrc > 0) {
|
||||
if (pollrc > 0 || idle_bitmask_save > 0) {
|
||||
//Handle idle event
|
||||
mpd_send_noidle(mpd.conn);
|
||||
mympd_parse_idle(s);
|
||||
if (pollrc > 0) {
|
||||
enum mpd_idle idle_bitmask = mpd_recv_idle(mpd.conn, false);
|
||||
mympd_parse_idle(s, idle_bitmask);
|
||||
}
|
||||
else {
|
||||
mpd_response_finish(mpd.conn);
|
||||
}
|
||||
if (idle_bitmask_save > 0) {
|
||||
//Handle idle event saved in mympd_callback
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "HANDLE SAVED IDLE EVENT\n");
|
||||
#endif
|
||||
mympd_parse_idle(s, idle_bitmask_save);
|
||||
idle_bitmask_save = 0;
|
||||
}
|
||||
mpd_send_idle(mpd.conn);
|
||||
}
|
||||
break;
|
||||
@ -682,66 +774,6 @@ void mympd_last_played_song_uri(const char *uri) {
|
||||
LOG_ERROR_AND_RECOVER("mpd_send_sticker_set");
|
||||
}
|
||||
|
||||
void mympd_parse_idle(struct mg_mgr *s) {
|
||||
enum mpd_idle idle_bitmask = mpd_recv_idle(mpd.conn, false);
|
||||
int len;
|
||||
|
||||
for (unsigned j = 0;; j ++) {
|
||||
enum mpd_idle idle_event = 1 << j;
|
||||
const char *idle_name = mpd_idle_name(idle_event);
|
||||
if (idle_name == NULL)
|
||||
break;
|
||||
if (idle_bitmask & idle_event) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "IDLE: %s\n", idle_name);
|
||||
#endif
|
||||
switch(idle_event) {
|
||||
case MPD_IDLE_DATABASE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_database\"}");
|
||||
break;
|
||||
case MPD_IDLE_STORED_PLAYLIST:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_stored_playlist\"}");
|
||||
break;
|
||||
case MPD_IDLE_QUEUE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_queue\"}");
|
||||
break;
|
||||
case MPD_IDLE_PLAYER:
|
||||
len = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version, &mpd.queue_length);
|
||||
if (config.stickers) {
|
||||
mympd_count_song_id(mpd.song_id, "playCount", 1);
|
||||
mympd_last_played_song_id(mpd.song_id);
|
||||
}
|
||||
break;
|
||||
case MPD_IDLE_MIXER:
|
||||
len = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version, &mpd.queue_length);
|
||||
break;
|
||||
case MPD_IDLE_OUTPUT:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_outputs\"}");
|
||||
break;
|
||||
case MPD_IDLE_OPTIONS:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_options\"}");
|
||||
break;
|
||||
case MPD_IDLE_UPDATE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_update\"}");
|
||||
break;
|
||||
case MPD_IDLE_STICKER:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_sticker\"}");
|
||||
break;
|
||||
case MPD_IDLE_SUBSCRIPTION:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_subscription\"}");
|
||||
break;
|
||||
case MPD_IDLE_MESSAGE:
|
||||
len = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"update_message\"}");
|
||||
break;
|
||||
default:
|
||||
len = 0;
|
||||
}
|
||||
if (len > 0)
|
||||
mympd_notify(s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) {
|
||||
char *str;
|
||||
|
@ -159,7 +159,7 @@ static int is_websocket(const struct mg_connection *nc) {
|
||||
}
|
||||
|
||||
void mympd_idle(struct mg_mgr *sm, int timeout);
|
||||
void mympd_parse_idle(struct mg_mgr *s);
|
||||
void mympd_parse_idle(struct mg_mgr *s, enum mpd_idle idle_bitmask);
|
||||
void callback_mympd(struct mg_connection *nc, const struct mg_str msg);
|
||||
void mympd_notify(struct mg_mgr *s);
|
||||
void mympd_count_song_id(int song_id, char *name, int value);
|
||||
|
Loading…
Reference in New Issue
Block a user