mirror of
https://github.com/SuperBFG7/ympd
synced 2025-01-12 18:30:36 +00:00
Feat: first backend code for editing smart playlists
This commit is contained in:
parent
45377cb047
commit
c4df10c71e
@ -360,8 +360,19 @@ function appInit() {
|
||||
document.getElementById('inputMixrampdelay').classList.remove('is-invalid');
|
||||
});
|
||||
|
||||
document.getElementById('selectJukeboxMode').addEventListener('change', function () {
|
||||
var value = this.options[this.selectedIndex].value;
|
||||
if (value == 0 || value == 2) {
|
||||
document.getElementById('inputJukeboxQueueLength').setAttribute('disabled', 'disabled');
|
||||
document.getElementById('selectJukeboxPlaylist').setAttribute('disabled', 'disabled');
|
||||
}
|
||||
else if (value == 1) {
|
||||
document.getElementById('inputJukeboxQueueLength').removeAttribute('disabled');
|
||||
document.getElementById('selectJukeboxPlaylist').removeAttribute('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('addToPlaylistPlaylist').addEventListener('change',function(event) {
|
||||
document.getElementById('addToPlaylistPlaylist').addEventListener('change', function (event) {
|
||||
if (this.options[this.selectedIndex].text == 'New Playlist') {
|
||||
document.getElementById('addToPlaylistNewPlaylistDiv').classList.remove('hide');
|
||||
document.getElementById('addToPlaylistNewPlaylist').focus();
|
||||
@ -874,6 +885,14 @@ function parseSettings(obj) {
|
||||
|
||||
document.getElementById('selectJukeboxMode').value = obj.data.jukeboxMode;
|
||||
document.getElementById('inputJukeboxQueueLength').value = obj.data.jukeboxQueueLength;
|
||||
if (obj.data.jukeboxMode == 0 || obj.data.jukeboxMode == 2) {
|
||||
document.getElementById('inputJukeboxQueueLength').setAttribute('disabled', 'disabled');
|
||||
document.getElementById('selectJukeboxPlaylist').setAttribute('disabled', 'disabled');
|
||||
}
|
||||
else if (obj.data.jukeboxMode == 1) {
|
||||
document.getElementById('inputJukeboxQueueLength').removeAttribute('disabled');
|
||||
document.getElementById('selectJukeboxPlaylist').removeAttribute('disabled');
|
||||
}
|
||||
|
||||
settings = obj.data;
|
||||
|
||||
@ -1629,7 +1648,7 @@ function saveSmartPlaylist() {
|
||||
var value = document.getElementById('saveSmartPlaylistName').value;
|
||||
var valid = value.replace(/[\w\-]/g, '');
|
||||
if (value != '' && valid == '') {
|
||||
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"playlist": value, "tag": app.current.filter, "searchstr": app.current.search}});
|
||||
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": "search", "playlist": value, "tag": app.current.filter, "searchstr": app.current.search}});
|
||||
modalSaveSmartPlaylist.hide();
|
||||
showNotification('Saved smart playlist ' + value, '', '', 'success');
|
||||
}
|
||||
|
209
src/mpd_client.c
209
src/mpd_client.c
@ -54,9 +54,9 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
size_t n = 0;
|
||||
char *cmd;
|
||||
unsigned int uint_buf1, uint_buf2, uint_rc;
|
||||
int je, int_buf, int_rc;
|
||||
int je, int_buf1, int_buf2, int_rc;
|
||||
float float_buf;
|
||||
char *p_charbuf1, *p_charbuf2, *p_charbuf3;
|
||||
char *p_charbuf1, *p_charbuf2, *p_charbuf3, *p_charbuf4;
|
||||
enum mpd_cmd_ids cmd_id;
|
||||
struct pollfd fds[1];
|
||||
int pollrc;
|
||||
@ -164,7 +164,7 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
mpd_run_mixrampdelay(mpd.conn, float_buf);
|
||||
}
|
||||
|
||||
je = json_scanf(msg.p, msg.len, "{data: {replaygain:%Q}}", &p_charbuf1);
|
||||
je = json_scanf(msg.p, msg.len, "{data: {replaygain: %Q}}", &p_charbuf1);
|
||||
if (je == 1) {
|
||||
mpd_send_command(mpd.conn, "replay_gain_mode", p_charbuf1, NULL);
|
||||
struct mpd_pair *pair;
|
||||
@ -196,13 +196,38 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Smart Playlists update failed\"}");
|
||||
break;
|
||||
case MPD_API_SMARTPLS_SAVE:
|
||||
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, tag: %Q, searchstr: %Q}}", &p_charbuf1, &p_charbuf2, &p_charbuf3);
|
||||
if (je == 3) {
|
||||
mympd_smartpls_save(p_charbuf1, p_charbuf2, p_charbuf3);
|
||||
je = json_scanf(msg.p, msg.len, "{data: {type: %Q}}", p_charbuf1);
|
||||
if (je == 1) {
|
||||
if (strcmp(p_charbuf1, "sticker") == 0) {
|
||||
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, sticker: %Q, maxentries: %d}}", &p_charbuf2, &p_charbuf3, &int_buf1);
|
||||
n = mympd_smartpls_save(p_charbuf1, p_charbuf2, p_charbuf3, NULL, int_buf1, 0);
|
||||
free(p_charbuf2);
|
||||
free(p_charbuf3);
|
||||
}
|
||||
else if (strcmp(p_charbuf1, "newest") == 0) {
|
||||
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, timerange: %d, maxentries: %d}}", &p_charbuf2, &int_buf1, &int_buf2);
|
||||
n = mympd_smartpls_save(p_charbuf1, p_charbuf2, NULL, NULL, int_buf2, int_buf1);
|
||||
free(p_charbuf2);
|
||||
}
|
||||
else if (strcmp(p_charbuf1, "search") == 0) {
|
||||
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, tag: %Q, searchstr: %Q}}", &p_charbuf2, &p_charbuf3, &p_charbuf4);
|
||||
n = mympd_smartpls_save(p_charbuf1, p_charbuf2, p_charbuf3, p_charbuf4, 0, 0);
|
||||
free(p_charbuf2);
|
||||
free(p_charbuf3);
|
||||
free(p_charbuf4);
|
||||
}
|
||||
free(p_charbuf1);
|
||||
free(p_charbuf2);
|
||||
free(p_charbuf3);
|
||||
}
|
||||
if (n == 0)
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||
else
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Error saving playlist\"}");
|
||||
break;
|
||||
case MPD_API_SMARTPLS_GET:
|
||||
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q}}", &p_charbuf1);
|
||||
if (je == 1) {
|
||||
n = mympd_smartpls_put(mpd.buf, p_charbuf1);
|
||||
free(p_charbuf1);
|
||||
}
|
||||
break;
|
||||
case MPD_API_PLAYER_PAUSE:
|
||||
@ -422,9 +447,9 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
}
|
||||
break;
|
||||
case MPD_API_QUEUE_ADD_TRACK_AFTER:
|
||||
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q, to:%d}}", &p_charbuf1, &int_buf);
|
||||
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q, to:%d}}", &p_charbuf1, &int_buf1);
|
||||
if (je == 2) {
|
||||
int_rc = mpd_run_add_id_to(mpd.conn, p_charbuf1, int_buf);
|
||||
int_rc = mpd_run_add_id_to(mpd.conn, p_charbuf1, int_buf1);
|
||||
if (int_rc > -1 )
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||
free(p_charbuf1);
|
||||
@ -451,9 +476,9 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
case MPD_API_QUEUE_ADD_PLAY_TRACK:
|
||||
je = json_scanf(msg.p, msg.len, "{data: {uri:%Q}}", &p_charbuf1);
|
||||
if (je == 1) {
|
||||
int_buf = mpd_run_add_id(mpd.conn, p_charbuf1);
|
||||
if (int_buf != -1)
|
||||
mpd_run_play_id(mpd.conn, int_buf);
|
||||
int_buf1 = mpd_run_add_id(mpd.conn, p_charbuf1);
|
||||
if (int_buf1 != -1)
|
||||
mpd_run_play_id(mpd.conn, int_buf1);
|
||||
free(p_charbuf1);
|
||||
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}");
|
||||
}
|
||||
@ -996,8 +1021,20 @@ void mympd_jukebox() {
|
||||
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
if (mympd_state.jukeboxMode == 2) {
|
||||
//Add whole album
|
||||
if (mympd_state.jukeboxMode == 1 && strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) {
|
||||
struct mpd_stats *stats = mpd_run_stats(mpd.conn);
|
||||
num_songs = mpd_stats_get_number_of_songs(stats);
|
||||
mpd_stats_free(stats);
|
||||
}
|
||||
else if (mympd_state.jukeboxMode == 1) {
|
||||
mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist);
|
||||
num_songs = 0;
|
||||
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||
num_songs++;
|
||||
mpd_entity_free(entity);
|
||||
}
|
||||
}
|
||||
else if (mympd_state.jukeboxMode == 2) {
|
||||
mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM);
|
||||
mpd_search_commit(mpd.conn);
|
||||
num_songs = 0;
|
||||
@ -1005,48 +1042,18 @@ void mympd_jukebox() {
|
||||
num_songs++;
|
||||
mpd_return_pair(mpd.conn, pair);
|
||||
}
|
||||
mpd_response_finish(mpd.conn);
|
||||
num_songs--;
|
||||
if (num_songs > 0) {
|
||||
rand_song = rand() % num_songs;
|
||||
mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM);
|
||||
mpd_search_commit(mpd.conn);
|
||||
i = 0;
|
||||
while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM )) != NULL) {
|
||||
if (i == rand_song) {
|
||||
album = strdup(pair->value);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
mpd_return_pair(mpd.conn, pair);
|
||||
}
|
||||
mpd_return_pair(mpd.conn, pair);
|
||||
mpd_response_finish(mpd.conn);
|
||||
printf("Jukebox enabled, adding random album %s: %d/%d\n", album, rand_song, num_songs);
|
||||
mpd_send_command(mpd.conn, "searchadd", "Album", album, NULL);
|
||||
mpd_response_finish(mpd.conn);
|
||||
}
|
||||
mpd_response_finish(mpd.conn);
|
||||
}
|
||||
else if (mympd_state.jukeboxMode == 1) {
|
||||
//Add tracks
|
||||
if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) {
|
||||
struct mpd_stats *stats = mpd_run_stats(mpd.conn);
|
||||
num_songs = mpd_stats_get_number_of_songs(stats);
|
||||
mpd_stats_free(stats);
|
||||
}
|
||||
else {
|
||||
mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist);
|
||||
num_songs = 0;
|
||||
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||
num_songs++;
|
||||
mpd_entity_free(entity);
|
||||
}
|
||||
}
|
||||
num_songs--;
|
||||
num_songs--;
|
||||
if (mympd_state.jukeboxMode == 1)
|
||||
addSongs = mympd_state.jukeboxQueueLength - queue_length;
|
||||
if (num_songs > 0) {
|
||||
for (j = 0; j < addSongs; j++) {
|
||||
rand_song = rand() % num_songs;
|
||||
else
|
||||
addSongs = 1;
|
||||
if (num_songs > 0) {
|
||||
for (j = 0; j < addSongs; j++) {
|
||||
rand_song = rand() % num_songs;
|
||||
if (mympd_state.jukeboxMode == 1) {
|
||||
//add songs
|
||||
if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0)
|
||||
mpd_send_list_all(mpd.conn, "/");
|
||||
else
|
||||
@ -1068,9 +1075,28 @@ void mympd_jukebox() {
|
||||
}
|
||||
mpd_entity_free(entity);
|
||||
}
|
||||
else if (mympd_state.jukeboxMode == 2) {
|
||||
//add album
|
||||
mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM);
|
||||
mpd_search_commit(mpd.conn);
|
||||
i = 0;
|
||||
while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM )) != NULL) {
|
||||
if (i == rand_song) {
|
||||
album = strdup(pair->value);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
mpd_return_pair(mpd.conn, pair);
|
||||
}
|
||||
mpd_return_pair(mpd.conn, pair);
|
||||
mpd_response_finish(mpd.conn);
|
||||
printf("Jukebox enabled, adding random album %s: %d/%d\n", album, rand_song, num_songs);
|
||||
mpd_send_command(mpd.conn, "searchadd", "Album", album, NULL);
|
||||
mpd_response_finish(mpd.conn);
|
||||
}
|
||||
}
|
||||
mpd_run_play(mpd.conn);
|
||||
}
|
||||
mpd_run_play(mpd.conn);
|
||||
}
|
||||
|
||||
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) {
|
||||
@ -1965,14 +1991,73 @@ void mympd_disconnect() {
|
||||
mympd_idle(NULL, 0);
|
||||
}
|
||||
|
||||
int mympd_smartpls_save(char *playlist, char *tag, char *searchstr) {
|
||||
int mympd_smartpls_put(char *buffer, char *playlist) {
|
||||
char pl_file[400];
|
||||
char *smartpltype;
|
||||
char *p_charbuf1, *p_charbuf2;
|
||||
int je, int_buf1, int_buf2;
|
||||
int len = 0;
|
||||
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||
|
||||
snprintf(pl_file, 400, "%s/smartpls/%s", config.varlibdir, playlist);
|
||||
char *content = json_fread(pl_file);
|
||||
je = json_scanf(content, strlen(content), "{type: %Q }", &smartpltype);
|
||||
if (je == 1) {
|
||||
if (strcmp(smartpltype, "sticker") == 0) {
|
||||
je = json_scanf(content, strlen(content), "{sticker: %Q, maxentries: %d}", &p_charbuf1, &int_buf1);
|
||||
if (je == 2) {
|
||||
len = json_printf(&out, "{type: smartpls, data: {type: %Q, sticker: %Q, maxentries: %d}",
|
||||
smartpltype,
|
||||
p_charbuf1,
|
||||
int_buf1);
|
||||
free(p_charbuf1);
|
||||
}
|
||||
}
|
||||
else if (strcmp(smartpltype, "newest") == 0) {
|
||||
je = json_scanf(content, strlen(content), "{timerange: %d, maxentries: %d}", &int_buf1, &int_buf2);
|
||||
if (je == 2) {
|
||||
len = json_printf(&out, "{type: smartpls, data: {type: %Q, timerange: %d, maxentries: %d}",
|
||||
smartpltype,
|
||||
int_buf1,
|
||||
int_buf2);
|
||||
}
|
||||
}
|
||||
else if (strcmp(smartpltype, "search") == 0) {
|
||||
je = json_scanf(content, strlen(content), "{tag: %Q, searchstr: %Q}", &p_charbuf1, &p_charbuf2);
|
||||
if (je == 2) {
|
||||
len = json_printf(&out, "{type: smartpls, data: {type: %Q, tag: %d, searchstr: %d}",
|
||||
smartpltype,
|
||||
p_charbuf1,
|
||||
p_charbuf2);
|
||||
free(p_charbuf1);
|
||||
free(p_charbuf2);
|
||||
}
|
||||
}
|
||||
free(smartpltype);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int mympd_smartpls_save(char *smartpltype, char *playlist, char *tag, char *searchstr, int maxentries, int timerange) {
|
||||
char tmp_file[400];
|
||||
char pl_file[400];
|
||||
snprintf(tmp_file, 400, "%s/tmp/%s", config.varlibdir, playlist);
|
||||
snprintf(pl_file, 400, "%s/smartpls/%s", config.varlibdir, playlist);
|
||||
json_fprintf(tmp_file, "{type: search, tag: %Q, searchstr: %Q}", tag, searchstr);
|
||||
rename(tmp_file, pl_file);
|
||||
mympd_smartpls_update_search(playlist, tag, searchstr);
|
||||
if (strcmp(smartpltype, "sticker") == 0) {
|
||||
json_fprintf(tmp_file, "{type: %Q, sticker: %Q, maxentries: %d}", smartpltype, tag, maxentries);
|
||||
rename(tmp_file, pl_file);
|
||||
mympd_smartpls_update(playlist, tag, maxentries);
|
||||
}
|
||||
else if (strcmp(smartpltype, "newest") == 0) {
|
||||
json_fprintf(tmp_file, "{type: %Q, timerange: %d, maxentries: %d}", smartpltype, timerange, maxentries);
|
||||
rename(tmp_file, pl_file);
|
||||
mympd_smartpls_update_newest(playlist, timerange, maxentries);
|
||||
}
|
||||
else if (strcmp(smartpltype, "search") == 0) {
|
||||
json_fprintf(tmp_file, "{type: %Q, tag: %Q, searchstr: %Q}", smartpltype, tag, searchstr);
|
||||
rename(tmp_file, pl_file);
|
||||
mympd_smartpls_update_search(playlist, tag, searchstr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2002,7 +2087,7 @@ int mympd_smartpls_update_all() {
|
||||
if (strcmp(smartpltype, "sticker") == 0) {
|
||||
je = json_scanf(content, strlen(content), "{sticker: %Q, maxentries: %d}", &p_charbuf1, &int_buf1);
|
||||
if (je == 2) {
|
||||
mympd_smartpls_update(p_charbuf1, ent->d_name, int_buf1);
|
||||
mympd_smartpls_update(ent->d_name, p_charbuf1, int_buf1);
|
||||
free(p_charbuf1);
|
||||
}
|
||||
else
|
||||
@ -2070,7 +2155,7 @@ int mympd_smartpls_update_search(char *playlist, char *tag, char *searchstr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mympd_smartpls_update(char *sticker, char *playlist, int maxentries) {
|
||||
int mympd_smartpls_update(char *playlist, char *sticker, int maxentries) {
|
||||
struct mpd_pair *pair;
|
||||
char *uri = NULL;
|
||||
char *name;
|
||||
|
@ -74,6 +74,7 @@
|
||||
X(MPD_API_PLAYLIST_CONTENT_LIST) \
|
||||
X(MPD_API_SMARTPLS_UPDATE_ALL) \
|
||||
X(MPD_API_SMARTPLS_SAVE) \
|
||||
X(MPD_API_SMARTPLS_GET) \
|
||||
X(MPD_API_DATABASE_SEARCH) \
|
||||
X(MPD_API_DATABASE_UPDATE) \
|
||||
X(MPD_API_DATABASE_RESCAN) \
|
||||
@ -200,8 +201,8 @@ void mympd_last_played_song_uri(const char *uri);
|
||||
void mympd_last_played_song_id(int song_id);
|
||||
void mympd_get_sticker(const char *uri, t_sticker *sticker);
|
||||
void mympd_jukebox();
|
||||
int mympd_smartpls_save(char *playlist, char *tag, char *searchstr);
|
||||
int mympd_smartpls_rm(char *playlist);
|
||||
int mympd_smartpls_save(char *smartpltype, char *playlist, char *tag, char *searchstr, int maxentries, int timerange);
|
||||
int mympd_smartpls_put(char *buffer, char *playlist);
|
||||
int mympd_smartpls_update_all();
|
||||
int mympd_smartpls_clear(char *playlist);
|
||||
int mympd_smartpls_update(char *sticker, char *playlist, int maxentries);
|
||||
|
Loading…
Reference in New Issue
Block a user