mirror of
https://github.com/SuperBFG7/ympd
synced 2025-05-04 16:34:07 +00:00
Fix: use central list functions for smart playlists and jukebox mode
This commit is contained in:
parent
25a8653510
commit
4e62c336ba
83
src/list.c
83
src/list.c
@ -1,10 +1,85 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include "list.h"
|
||||
|
||||
int list_init(struct list *list) {
|
||||
list->length = 0;
|
||||
list->list = NULL;
|
||||
int list_init(struct list *l) {
|
||||
l->length = 0;
|
||||
l->list = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct node *list_node_at(const struct list * l, unsigned index) {
|
||||
/* if there's no data in the list, fail */
|
||||
if (l->list == NULL) { return NULL; }
|
||||
struct node * current = l->list;
|
||||
for (; index > 0; index--) {
|
||||
if (current->next == NULL) { return NULL; }
|
||||
current = current->next;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
int list_swap_item(struct node *n1, struct node *n2) {
|
||||
if (n1 == n2)
|
||||
return 1;
|
||||
|
||||
if (n1 == NULL || n2 == NULL)
|
||||
return 1;
|
||||
|
||||
int value = n2->value;
|
||||
char *data;
|
||||
data = malloc(strlen(n2->data));
|
||||
data = strdup(n2->data);
|
||||
|
||||
n2->value = n1->value;
|
||||
n2->data = realloc(n2->data, strlen(n1->data));
|
||||
n2->data = strdup(n1->data);
|
||||
|
||||
n1->value = value;
|
||||
n1->data = realloc(n1->data, strlen(data));
|
||||
n1->data = strdup(data);
|
||||
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int list_shuffle(struct list *l) {
|
||||
int pos;
|
||||
int n = 0;
|
||||
|
||||
if (l->length < 2)
|
||||
return 1;
|
||||
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
struct node *current = l->list;
|
||||
while (current != NULL) {
|
||||
pos = rand() / (RAND_MAX / (l->length - n + 1) + 1);
|
||||
list_swap_item(current, list_node_at(l, pos));
|
||||
n++;
|
||||
current = current->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int list_replace(struct list *l, int pos, char *data, int value) {
|
||||
int i = 0;
|
||||
struct node *current = l->list;
|
||||
while (current->next != NULL) {
|
||||
if (i == pos)
|
||||
break;
|
||||
current = current->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
current->value = value;
|
||||
current->data = realloc(current->data, strlen(data));
|
||||
current->data = strdup(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -25,7 +100,7 @@ int list_push(struct list *l, char *data, int value) {
|
||||
}
|
||||
|
||||
int list_free(struct list *l) {
|
||||
struct node * current = l->list, *tmp = NULL;
|
||||
struct node *current = l->list, *tmp = NULL;
|
||||
while (current != NULL) {
|
||||
free(current->data);
|
||||
tmp = current;
|
||||
|
@ -4,12 +4,18 @@ struct node {
|
||||
struct node *next;
|
||||
};
|
||||
|
||||
|
||||
struct list {
|
||||
unsigned length;
|
||||
struct node *list;
|
||||
};
|
||||
|
||||
|
||||
int list_init(struct list *);
|
||||
int list_init(struct list *l);
|
||||
int list_push(struct list *l, char *data, int value);
|
||||
int list_replace(struct list *l, int pos, char *data, int value);
|
||||
int list_free(struct list *l);
|
||||
|
||||
int list_shuffle(struct list *l);
|
||||
int list_swap_item(struct node *n1, struct node *n2);
|
||||
struct node *list_node_at(const struct list * l, unsigned index);
|
||||
|
162
src/mpd_client.c
162
src/mpd_client.c
@ -211,8 +211,8 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
|
||||
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);
|
||||
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, timerange: %d}}", &p_charbuf2, &int_buf1);
|
||||
n = mympd_smartpls_save(p_charbuf1, p_charbuf2, NULL, NULL, 0, int_buf1);
|
||||
free(p_charbuf2);
|
||||
}
|
||||
else if (strcmp(p_charbuf1, "search") == 0) {
|
||||
@ -1068,21 +1068,11 @@ void mympd_jukebox() {
|
||||
i = randrange(addSongs);
|
||||
if (addSongs == 1) {
|
||||
song = mpd_entity_get_song(entity);
|
||||
list_free(&add_list);
|
||||
list_push(&add_list, mpd_song_get_uri(song), lineno);
|
||||
list_replace(&add_list, 0, mpd_song_get_uri(song), lineno);
|
||||
}
|
||||
else {
|
||||
song = mpd_entity_get_song(entity);
|
||||
/*
|
||||
int nm = nr - i - 1;
|
||||
if (nm > 0) {
|
||||
struct aline tmp = keeplines[i];
|
||||
memmove(&keeplines[i], &keeplines[i+1], nm * sizeof(*keeplines));
|
||||
keeplines[nkeep-1] = tmp;
|
||||
}
|
||||
savestr(&keeplines[nkeep-1], line);
|
||||
*/
|
||||
// list_push(&add_list, mpd_song_get_uri(song), lineno);
|
||||
list_replace(&add_list, i, mpd_song_get_uri(song), lineno);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1114,11 +1104,10 @@ void mympd_jukebox() {
|
||||
if (addSongs > 1)
|
||||
i = randrange(addSongs);
|
||||
if (addSongs == 1) {
|
||||
list_free(&add_list);
|
||||
list_push(&add_list, strdup(pair->value), lineno);
|
||||
list_replace(&add_list, 0, strdup(pair->value), lineno);
|
||||
}
|
||||
else {
|
||||
list_push(&add_list, strdup(pair->value), lineno);
|
||||
list_replace(&add_list, i, strdup(pair->value), lineno);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1126,11 +1115,12 @@ void mympd_jukebox() {
|
||||
mpd_return_pair(mpd.conn, pair);
|
||||
}
|
||||
}
|
||||
|
||||
if (nkeep < addSongs) {
|
||||
fprintf(stderr, "Warning: input didn't contain %d entries\n", addSongs);
|
||||
}
|
||||
|
||||
// list_shuffle(&add_list);
|
||||
list_shuffle(&add_list);
|
||||
|
||||
struct node *current = add_list.list;
|
||||
while (current != NULL) {
|
||||
@ -2095,7 +2085,7 @@ 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 je, int_buf1;
|
||||
int len = 0;
|
||||
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
|
||||
|
||||
@ -2115,13 +2105,12 @@ int mympd_smartpls_put(char *buffer, char *playlist) {
|
||||
}
|
||||
}
|
||||
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: {playlist: %Q, type: %Q, timerange: %d, maxentries: %d}}",
|
||||
je = json_scanf(content, strlen(content), "{timerange: %d}", &int_buf1);
|
||||
if (je == 1) {
|
||||
len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, timerange: %d}}",
|
||||
playlist,
|
||||
smartpltype,
|
||||
int_buf1,
|
||||
int_buf2);
|
||||
int_buf1);
|
||||
}
|
||||
}
|
||||
else if (strcmp(smartpltype, "search") == 0) {
|
||||
@ -2152,9 +2141,9 @@ int mympd_smartpls_save(char *smartpltype, char *playlist, char *tag, char *sear
|
||||
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);
|
||||
json_fprintf(tmp_file, "{type: %Q, timerange: %d}", smartpltype, timerange);
|
||||
rename(tmp_file, pl_file);
|
||||
mympd_smartpls_update_newest(playlist, timerange, maxentries);
|
||||
mympd_smartpls_update_newest(playlist, timerange);
|
||||
}
|
||||
else if (strcmp(smartpltype, "search") == 0) {
|
||||
json_fprintf(tmp_file, "{type: %Q, tag: %Q, searchstr: %Q}", smartpltype, tag, searchstr);
|
||||
@ -2172,7 +2161,7 @@ int mympd_smartpls_update_all() {
|
||||
char dirname[400];
|
||||
int je;
|
||||
char *p_charbuf1, *p_charbuf2;
|
||||
int int_buf1, int_buf2;
|
||||
int int_buf1;
|
||||
|
||||
if (!config.smartpls)
|
||||
return 0;
|
||||
@ -2197,9 +2186,9 @@ int mympd_smartpls_update_all() {
|
||||
printf("Can't parse file %s\n", filename);
|
||||
}
|
||||
else if (strcmp(smartpltype, "newest") == 0) {
|
||||
je = json_scanf(content, strlen(content), "{timerange: %d, maxentries: %d}", &int_buf1, &int_buf2);
|
||||
if (je == 2) {
|
||||
mympd_smartpls_update_newest(ent->d_name, int_buf1, int_buf2);
|
||||
je = json_scanf(content, strlen(content), "{timerange: %d}", &int_buf1);
|
||||
if (je == 1) {
|
||||
mympd_smartpls_update_newest(ent->d_name, int_buf1);
|
||||
}
|
||||
else
|
||||
printf("Can't parse file %s\n", filename);
|
||||
@ -2264,23 +2253,18 @@ int mympd_smartpls_update(char *playlist, char *sticker, int maxentries) {
|
||||
char *name;
|
||||
char *p_value;
|
||||
char *crap;
|
||||
char tmpfile[400];
|
||||
long value;
|
||||
long value_max = 0;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
long i = 0;
|
||||
|
||||
if (!mpd_send_sticker_find(mpd.conn, "song", "", sticker)) {
|
||||
LOG_ERROR_AND_RECOVER("mpd_send_sticker_find");
|
||||
return 1;
|
||||
}
|
||||
snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir);
|
||||
FILE *fp = fopen(tmpfile, "w");
|
||||
if (fp == NULL) {
|
||||
printf("Error opening %s\n", tmpfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct list add_list;
|
||||
list_init(&add_list);
|
||||
|
||||
while ((pair = mpd_recv_pair(mpd.conn)) != NULL) {
|
||||
if (strcmp(pair->name, "file") == 0) {
|
||||
uri = strdup(pair->value);
|
||||
@ -2290,59 +2274,42 @@ int mympd_smartpls_update(char *playlist, char *sticker, int maxentries) {
|
||||
p_value = strtok(NULL, "=");
|
||||
value = strtol(p_value, &crap, 10);
|
||||
if (value > 1)
|
||||
fprintf(fp, "%s::%ld\n", uri, value);
|
||||
list_push(&add_list, uri, value);
|
||||
if (value > value_max)
|
||||
value_max = value;
|
||||
}
|
||||
mpd_return_pair(mpd.conn, pair);
|
||||
}
|
||||
mpd_response_finish(mpd.conn);
|
||||
fclose(fp);
|
||||
free(uri);
|
||||
|
||||
mympd_smartpls_clear(playlist);
|
||||
|
||||
if (value_max > 2)
|
||||
value_max = value_max / 2;
|
||||
fp = fopen(tmpfile, "r");
|
||||
if (fp == NULL) {
|
||||
printf("Error opening %s\n", tmpfile);
|
||||
return 1;
|
||||
}
|
||||
while ((read = getline(&uri, &len, fp)) != -1) {
|
||||
name = strtok(uri, "::");
|
||||
p_value = strtok(NULL, "::");
|
||||
value = strtol(p_value, &crap, 10);
|
||||
if (value < value_max)
|
||||
continue;
|
||||
if (!mpd_run_playlist_add(mpd.conn, playlist, name)) {
|
||||
LOG_ERROR_AND_RECOVER("mpd_run_playlist_add");
|
||||
fclose(fp);
|
||||
free(uri);
|
||||
unlink(tmpfile);
|
||||
return 1;
|
||||
|
||||
struct node *current = add_list.list;
|
||||
while (current != NULL) {
|
||||
if (current->value >= value_max) {
|
||||
if (!mpd_run_playlist_add(mpd.conn, playlist, current->data)) {
|
||||
LOG_ERROR_AND_RECOVER("mpd_run_playlist_add");
|
||||
list_free(&add_list);
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
if (i >= maxentries)
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
if (i >= maxentries)
|
||||
break;
|
||||
current = current->next;
|
||||
}
|
||||
fclose(fp);
|
||||
free(uri);
|
||||
unlink(tmpfile);
|
||||
list_free(&add_list);
|
||||
printf("Updated %s with %ld songs, minValue: %ld\n", playlist, i, value_max);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries) {
|
||||
struct mpd_song *song;
|
||||
char *uri;
|
||||
char *name;
|
||||
char tmpfile[400];
|
||||
unsigned long value;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
long i = 0;
|
||||
int mympd_smartpls_update_newest(char *playlist, int timerange) {
|
||||
unsigned long value_max = 0;
|
||||
char search[20];
|
||||
char searchstr[20];
|
||||
|
||||
struct mpd_stats *stats = mpd_run_stats(mpd.conn);
|
||||
if (stats != NULL) {
|
||||
@ -2356,51 +2323,10 @@ int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries)
|
||||
|
||||
mympd_smartpls_clear(playlist);
|
||||
value_max -= timerange;
|
||||
snprintf(search, 20, "%lu", value_max);
|
||||
|
||||
if (value_max > 0) {
|
||||
if (mpd_send_command(mpd.conn, "find", "modified-since", search, NULL) == false) {
|
||||
LOG_ERROR_AND_RECOVER("mpd_find");
|
||||
return 1;
|
||||
}
|
||||
snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir);
|
||||
FILE *fp = fopen(tmpfile, "w");
|
||||
if (fp == NULL) {
|
||||
printf("Error opening %s\n", tmpfile);
|
||||
return 1;
|
||||
}
|
||||
while ((song = mpd_recv_song(mpd.conn)) != NULL) {
|
||||
value = mpd_song_get_last_modified(song);
|
||||
fprintf(fp, "%s::%lu\n", mpd_song_get_uri(song), value);
|
||||
mpd_song_free(song);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
fp = fopen(tmpfile, "r");
|
||||
if (fp == NULL) {
|
||||
printf("Error opening %s\n", tmpfile);
|
||||
return 1;
|
||||
}
|
||||
while ((read = getline(&uri, &len, fp)) != -1) {
|
||||
name = strtok(uri, "::");
|
||||
if (!mpd_run_playlist_add(mpd.conn, playlist, name)) {
|
||||
LOG_ERROR_AND_RECOVER("mpd_run_playlist_add");
|
||||
fclose(fp);
|
||||
unlink(tmpfile);
|
||||
free(uri);
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
if (i >= maxentries)
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
free(uri);
|
||||
printf("Updated %s with %ld songs, minValue: %ld\n", playlist, i, value_max);
|
||||
snprintf(searchstr, 20, "%lu", value_max);
|
||||
mympd_search(mpd.buf, searchstr, "modified-since", playlist, 0);
|
||||
printf("Updated %s\n", playlist);
|
||||
}
|
||||
else {
|
||||
printf("Error updating %s\n", playlist);
|
||||
}
|
||||
unlink(tmpfile);
|
||||
return 0;
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ 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);
|
||||
int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries);
|
||||
int mympd_smartpls_update_newest(char *playlist, int timerange);
|
||||
int mympd_smartpls_update_search(char *playlist, char *tag, char *searchstr);
|
||||
int mympd_get_updatedb_state(char *buffer);
|
||||
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length);
|
||||
|
Loading…
x
Reference in New Issue
Block a user