2018-05-24 17:50:05 +00:00
|
|
|
/* myMPD
|
|
|
|
(c) 2018 Juergen Mang <mail@jcgames.de>
|
2018-06-21 21:29:49 +00:00
|
|
|
This project's homepage is: https://github.com/jcorporation/mympd
|
2018-05-24 17:50:05 +00:00
|
|
|
|
|
|
|
myMPD ist fork of:
|
|
|
|
|
|
|
|
ympd
|
2014-02-22 00:57:26 +00:00
|
|
|
(c) 2013-2014 Andrew Karpow <andy@ndyk.de>
|
2014-01-17 18:41:41 +00:00
|
|
|
This project's homepage is: http://www.ympd.org
|
2014-02-22 00:57:26 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; version 2 of the License.
|
2014-01-17 18:41:41 +00:00
|
|
|
|
2014-02-22 00:57:26 +00:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2014-01-17 18:41:41 +00:00
|
|
|
|
2014-02-22 00:57:26 +00:00
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2014-01-17 18:41:41 +00:00
|
|
|
*/
|
|
|
|
|
2014-01-08 01:23:02 +00:00
|
|
|
#ifndef __MPD_CLIENT_H__
|
|
|
|
#define __MPD_CLIENT_H__
|
|
|
|
|
2018-07-30 22:05:37 +00:00
|
|
|
#include "../dist/src/mongoose/mongoose.h"
|
2018-10-09 21:51:47 +00:00
|
|
|
#include "list.h"
|
2013-11-04 17:18:38 +00:00
|
|
|
|
2014-02-22 00:57:26 +00:00
|
|
|
#define RETURN_ERROR_AND_RECOVER(X) do { \
|
2018-10-25 20:03:33 +00:00
|
|
|
printf("MPD %s: %s\n", X, mpd_connection_get_error_message(mpd.conn)); \
|
|
|
|
len = json_printf(&out, "{ type:error, data : %Q }", mpd_connection_get_error_message(mpd.conn)); \
|
2014-02-22 00:57:26 +00:00
|
|
|
if (!mpd_connection_clear_error(mpd.conn)) \
|
|
|
|
mpd.conn_state = MPD_FAILURE; \
|
2018-06-18 16:53:30 +00:00
|
|
|
return len; \
|
2018-08-06 21:29:20 +00:00
|
|
|
} while (0)
|
2014-02-22 00:57:26 +00:00
|
|
|
|
2018-08-22 00:13:30 +00:00
|
|
|
#define LOG_ERROR_AND_RECOVER(X) do { \
|
2018-10-25 20:03:33 +00:00
|
|
|
printf("MPD %s: %s\n", X, mpd_connection_get_error_message(mpd.conn)); \
|
2018-08-22 00:13:30 +00:00
|
|
|
if (!mpd_connection_clear_error(mpd.conn)) \
|
|
|
|
mpd.conn_state = MPD_FAILURE; \
|
|
|
|
} while (0)
|
2014-02-22 00:57:26 +00:00
|
|
|
|
2018-10-14 22:03:56 +00:00
|
|
|
#define CHECK_RETURN_LEN() do { \
|
|
|
|
if (len > MAX_SIZE) \
|
|
|
|
printf("Buffer truncated: %d, %d\n", len, MAX_SIZE); \
|
|
|
|
return len; \
|
|
|
|
} while (0)
|
|
|
|
|
2018-10-17 22:04:06 +00:00
|
|
|
#define PUT_SONG_TAGS() do { \
|
|
|
|
struct node *current = mympd_tags.list; \
|
|
|
|
int tagnr = 0; \
|
|
|
|
while (current != NULL) { \
|
|
|
|
if (tagnr ++) \
|
|
|
|
len += json_printf(&out, ","); \
|
|
|
|
len += json_printf(&out, "%Q: %Q", current->data, mympd_get_tag(song, mpd_tag_name_parse(current->data))); \
|
|
|
|
current = current->next; \
|
|
|
|
} \
|
2018-10-22 20:03:45 +00:00
|
|
|
len += json_printf(&out, ", Duration: %d, uri: %Q", mpd_song_get_duration(song), mpd_song_get_uri(song)); \
|
2018-10-17 22:04:06 +00:00
|
|
|
} while (0)
|
|
|
|
|
2018-10-25 20:03:33 +00:00
|
|
|
#define PUT_MIN_SONG_TAGS() do { \
|
|
|
|
len += json_printf(&out, "Title: %Q, Duration: %d, uri: %Q", mympd_get_tag(song, MPD_TAG_TITLE), mpd_song_get_duration(song), mpd_song_get_uri(song)); \
|
|
|
|
} while (0)
|
|
|
|
|
2018-10-17 22:04:06 +00:00
|
|
|
|
2018-11-28 14:23:29 +00:00
|
|
|
#define LOG_INFO() if (config.loglevel >= 1)
|
|
|
|
#define LOG_VERBOSE() if (config.loglevel >= 2)
|
|
|
|
#define LOG_DEBUG() if (config.loglevel == 3)
|
2018-11-27 21:24:45 +00:00
|
|
|
|
2018-10-14 22:03:56 +00:00
|
|
|
#define MAX_SIZE 2048 * 400
|
|
|
|
#define MAX_ELEMENTS_PER_PAGE 400
|
2014-02-22 01:11:45 +00:00
|
|
|
|
2014-02-16 18:46:53 +00:00
|
|
|
#define GEN_ENUM(X) X,
|
|
|
|
#define GEN_STR(X) #X,
|
|
|
|
#define MPD_CMDS(X) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_QUEUE_CLEAR) \
|
|
|
|
X(MPD_API_QUEUE_CROP) \
|
|
|
|
X(MPD_API_QUEUE_SAVE) \
|
|
|
|
X(MPD_API_QUEUE_LIST) \
|
|
|
|
X(MPD_API_QUEUE_SEARCH) \
|
|
|
|
X(MPD_API_QUEUE_RM_TRACK) \
|
|
|
|
X(MPD_API_QUEUE_RM_RANGE) \
|
|
|
|
X(MPD_API_QUEUE_MOVE_TRACK) \
|
|
|
|
X(MPD_API_QUEUE_ADD_TRACK_AFTER) \
|
|
|
|
X(MPD_API_QUEUE_ADD_TRACK) \
|
|
|
|
X(MPD_API_QUEUE_ADD_PLAY_TRACK) \
|
|
|
|
X(MPD_API_QUEUE_REPLACE_TRACK) \
|
|
|
|
X(MPD_API_QUEUE_ADD_PLAYLIST) \
|
|
|
|
X(MPD_API_QUEUE_REPLACE_PLAYLIST) \
|
|
|
|
X(MPD_API_QUEUE_SHUFFLE) \
|
2018-11-12 23:48:29 +00:00
|
|
|
X(MPD_API_QUEUE_LAST_PLAYED) \
|
2018-07-22 19:00:26 +00:00
|
|
|
X(MPD_API_PLAYLIST_CLEAR) \
|
|
|
|
X(MPD_API_PLAYLIST_RENAME) \
|
2018-07-26 21:48:03 +00:00
|
|
|
X(MPD_API_PLAYLIST_MOVE_TRACK) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_PLAYLIST_ADD_TRACK) \
|
|
|
|
X(MPD_API_PLAYLIST_RM_TRACK) \
|
2018-10-15 20:13:57 +00:00
|
|
|
X(MPD_API_PLAYLIST_RM) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_PLAYLIST_LIST) \
|
|
|
|
X(MPD_API_PLAYLIST_CONTENT_LIST) \
|
2018-09-29 23:03:00 +00:00
|
|
|
X(MPD_API_SMARTPLS_UPDATE_ALL) \
|
2018-09-26 22:10:51 +00:00
|
|
|
X(MPD_API_SMARTPLS_SAVE) \
|
2018-09-30 22:18:55 +00:00
|
|
|
X(MPD_API_SMARTPLS_GET) \
|
2018-11-27 13:05:51 +00:00
|
|
|
X(MPD_API_DATABASE_SEARCH_ADV) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_DATABASE_SEARCH) \
|
|
|
|
X(MPD_API_DATABASE_UPDATE) \
|
2018-09-23 21:48:12 +00:00
|
|
|
X(MPD_API_DATABASE_RESCAN) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_DATABASE_FILESYSTEM_LIST) \
|
2018-09-10 20:32:15 +00:00
|
|
|
X(MPD_API_DATABASE_TAG_LIST) \
|
|
|
|
X(MPD_API_DATABASE_TAG_ALBUM_LIST) \
|
|
|
|
X(MPD_API_DATABASE_TAG_ALBUM_TITLE_LIST) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_DATABASE_STATS) \
|
|
|
|
X(MPD_API_DATABASE_SONGDETAILS) \
|
|
|
|
X(MPD_API_PLAYER_PLAY_TRACK) \
|
2018-10-11 19:50:26 +00:00
|
|
|
X(MPD_API_PLAYER_VOLUME_SET) \
|
|
|
|
X(MPD_API_PLAYER_VOLUME_GET) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_PLAYER_PAUSE) \
|
|
|
|
X(MPD_API_PLAYER_PLAY) \
|
|
|
|
X(MPD_API_PLAYER_STOP) \
|
|
|
|
X(MPD_API_PLAYER_SEEK) \
|
|
|
|
X(MPD_API_PLAYER_NEXT) \
|
|
|
|
X(MPD_API_PLAYER_PREV) \
|
|
|
|
X(MPD_API_PLAYER_OUTPUT_LIST) \
|
|
|
|
X(MPD_API_PLAYER_TOGGLE_OUTPUT) \
|
|
|
|
X(MPD_API_PLAYER_CURRENT_SONG) \
|
|
|
|
X(MPD_API_PLAYER_STATE) \
|
|
|
|
X(MPD_API_SETTINGS_GET) \
|
|
|
|
X(MPD_API_SETTINGS_SET) \
|
2018-06-19 22:43:36 +00:00
|
|
|
X(MPD_API_WELCOME) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_LIKE) \
|
2018-10-15 22:34:25 +00:00
|
|
|
X(MPD_API_SYSCMD) \
|
2018-10-22 20:03:45 +00:00
|
|
|
X(MPD_API_COLS_SAVE) \
|
2018-08-27 18:47:00 +00:00
|
|
|
X(MPD_API_UNKNOWN)
|
2014-01-08 01:23:02 +00:00
|
|
|
|
2014-02-16 18:46:53 +00:00
|
|
|
enum mpd_cmd_ids {
|
|
|
|
MPD_CMDS(GEN_ENUM)
|
2013-11-09 01:07:03 +00:00
|
|
|
};
|
2013-11-04 17:18:38 +00:00
|
|
|
|
2013-11-09 01:07:03 +00:00
|
|
|
enum mpd_conn_states {
|
|
|
|
MPD_DISCONNECTED,
|
2014-02-16 18:46:53 +00:00
|
|
|
MPD_FAILURE,
|
2014-02-04 16:58:10 +00:00
|
|
|
MPD_CONNECTED,
|
2014-02-16 18:46:53 +00:00
|
|
|
MPD_RECONNECT,
|
|
|
|
MPD_DISCONNECT
|
2013-11-09 01:07:03 +00:00
|
|
|
};
|
2013-11-04 17:18:38 +00:00
|
|
|
|
2014-02-16 18:46:53 +00:00
|
|
|
struct t_mpd {
|
2018-09-03 21:49:55 +00:00
|
|
|
// Connection
|
2014-02-16 18:46:53 +00:00
|
|
|
struct mpd_connection *conn;
|
|
|
|
enum mpd_conn_states conn_state;
|
2018-09-03 21:49:55 +00:00
|
|
|
int timeout;
|
2014-02-16 18:46:53 +00:00
|
|
|
|
2018-09-03 21:49:55 +00:00
|
|
|
// Reponse Buffer
|
2014-02-16 18:46:53 +00:00
|
|
|
char buf[MAX_SIZE];
|
|
|
|
size_t buf_size;
|
|
|
|
|
2018-09-03 21:49:55 +00:00
|
|
|
// States
|
2014-02-16 18:46:53 +00:00
|
|
|
int song_id;
|
2018-05-28 18:48:43 +00:00
|
|
|
int next_song_id;
|
2018-08-23 15:24:37 +00:00
|
|
|
int last_song_id;
|
2014-02-16 18:46:53 +00:00
|
|
|
unsigned queue_version;
|
2018-08-21 22:56:17 +00:00
|
|
|
unsigned queue_length;
|
2018-08-24 10:19:59 +00:00
|
|
|
int last_update_sticker_song_id;
|
2018-11-12 23:48:29 +00:00
|
|
|
int last_last_played_id;
|
2018-09-03 21:49:55 +00:00
|
|
|
|
|
|
|
// Features
|
2018-09-03 22:20:28 +00:00
|
|
|
const unsigned* protocol;
|
2018-09-11 19:59:33 +00:00
|
|
|
// Supported tags
|
2018-09-03 21:49:55 +00:00
|
|
|
bool feat_sticker;
|
2018-10-25 20:03:33 +00:00
|
|
|
bool feat_playlists;
|
|
|
|
bool feat_tags;
|
2018-10-29 19:41:04 +00:00
|
|
|
bool feat_library;
|
2018-11-22 23:23:53 +00:00
|
|
|
bool feat_advsearch;
|
2014-02-16 18:46:53 +00:00
|
|
|
} mpd;
|
|
|
|
|
2018-10-09 21:51:47 +00:00
|
|
|
struct list mpd_tags;
|
|
|
|
struct list mympd_tags;
|
2018-10-29 18:17:04 +00:00
|
|
|
struct list mympd_searchtags;
|
|
|
|
struct list mympd_browsetags;
|
2018-11-12 23:48:29 +00:00
|
|
|
struct list last_played;
|
2018-10-15 22:34:25 +00:00
|
|
|
struct list syscmds;
|
|
|
|
|
2018-08-06 20:51:48 +00:00
|
|
|
typedef struct {
|
2018-08-22 12:25:02 +00:00
|
|
|
long mpdport;
|
2018-11-04 23:26:59 +00:00
|
|
|
const char *mpdhost;
|
|
|
|
const char *mpdpass;
|
|
|
|
const char *webport;
|
2018-08-15 13:06:45 +00:00
|
|
|
bool ssl;
|
2018-11-04 23:26:59 +00:00
|
|
|
const char *sslport;
|
|
|
|
const char *sslcert;
|
|
|
|
const char *sslkey;
|
|
|
|
const char *user;
|
2018-10-29 19:41:04 +00:00
|
|
|
bool coverimage;
|
2018-11-04 23:26:59 +00:00
|
|
|
const char *coverimagename;
|
2018-08-21 19:28:13 +00:00
|
|
|
bool stickers;
|
|
|
|
bool mixramp;
|
2018-11-04 23:26:59 +00:00
|
|
|
const char *taglist;
|
|
|
|
const char *searchtaglist;
|
|
|
|
const char *browsetaglist;
|
2018-09-24 22:27:24 +00:00
|
|
|
bool smartpls;
|
2018-11-04 23:26:59 +00:00
|
|
|
const char *varlibdir;
|
|
|
|
const char *etcdir;
|
2018-10-18 21:33:11 +00:00
|
|
|
unsigned long max_elements_per_page;
|
2018-10-29 18:17:04 +00:00
|
|
|
bool syscmds;
|
|
|
|
bool localplayer;
|
|
|
|
long streamport;
|
2018-11-04 23:26:59 +00:00
|
|
|
const char *streamurl;
|
2018-11-12 23:48:29 +00:00
|
|
|
unsigned long last_played_count;
|
2018-11-27 21:24:45 +00:00
|
|
|
long loglevel;
|
2018-08-17 09:52:22 +00:00
|
|
|
} t_config;
|
2018-08-06 20:51:48 +00:00
|
|
|
|
2018-08-17 09:52:22 +00:00
|
|
|
t_config config;
|
|
|
|
|
|
|
|
typedef struct {
|
2018-08-22 12:25:02 +00:00
|
|
|
long playCount;
|
|
|
|
long skipCount;
|
|
|
|
long lastPlayed;
|
|
|
|
long like;
|
2018-08-17 09:52:22 +00:00
|
|
|
} t_sticker;
|
2018-05-24 17:50:05 +00:00
|
|
|
|
2018-09-17 22:25:05 +00:00
|
|
|
typedef struct {
|
|
|
|
bool notificationWeb;
|
|
|
|
bool notificationPage;
|
2018-09-30 01:03:33 +00:00
|
|
|
int jukeboxMode;
|
2018-11-04 23:26:59 +00:00
|
|
|
const char *jukeboxPlaylist;
|
2018-09-30 01:03:33 +00:00
|
|
|
int jukeboxQueueLength;
|
2018-11-14 23:14:47 +00:00
|
|
|
char *colsQueueCurrent;
|
2018-11-04 23:26:59 +00:00
|
|
|
char *colsSearch;
|
|
|
|
char *colsBrowseDatabase;
|
|
|
|
char *colsBrowsePlaylistsDetail;
|
|
|
|
char *colsBrowseFilesystem;
|
|
|
|
char *colsPlayback;
|
2018-11-14 23:14:47 +00:00
|
|
|
char *colsQueueLastPlayed;
|
2018-09-17 22:25:05 +00:00
|
|
|
} t_mympd_state;
|
|
|
|
|
|
|
|
t_mympd_state mympd_state;
|
|
|
|
|
2018-06-12 00:07:03 +00:00
|
|
|
static int is_websocket(const struct mg_connection *nc) {
|
2018-08-15 13:06:45 +00:00
|
|
|
return nc->flags & MG_F_IS_WEBSOCKET;
|
2018-06-12 23:29:58 +00:00
|
|
|
}
|
2018-06-12 00:07:03 +00:00
|
|
|
|
2018-10-03 22:24:14 +00:00
|
|
|
int randrange(int n);
|
2018-08-22 00:13:30 +00:00
|
|
|
void mympd_idle(struct mg_mgr *sm, int timeout);
|
2018-08-23 15:24:37 +00:00
|
|
|
void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask);
|
2018-06-14 22:00:54 +00:00
|
|
|
void callback_mympd(struct mg_connection *nc, const struct mg_str msg);
|
2018-08-15 13:06:45 +00:00
|
|
|
void mympd_notify(struct mg_mgr *s);
|
2018-08-15 15:23:47 +00:00
|
|
|
void mympd_count_song_id(int song_id, char *name, int value);
|
|
|
|
void mympd_count_song_uri(const char *uri, char *name, int value);
|
|
|
|
void mympd_like_song_uri(const char *uri, int value);
|
2018-08-15 16:06:12 +00:00
|
|
|
void mympd_last_played_song_uri(const char *uri);
|
|
|
|
void mympd_last_played_song_id(int song_id);
|
2018-08-17 09:52:22 +00:00
|
|
|
void mympd_get_sticker(const char *uri, t_sticker *sticker);
|
2018-11-12 23:48:29 +00:00
|
|
|
void mympd_last_played_list(int song_id);
|
2018-09-17 22:25:05 +00:00
|
|
|
void mympd_jukebox();
|
2018-10-01 19:13:38 +00:00
|
|
|
bool mympd_state_get(char *name, char *value);
|
2018-10-18 21:33:11 +00:00
|
|
|
bool mympd_state_set(const char *name, const char *value);
|
2018-10-16 21:38:38 +00:00
|
|
|
int mympd_syscmd(char *buffer, char *cmd, int order);
|
2018-09-30 22:18:55 +00:00
|
|
|
int mympd_smartpls_save(char *smartpltype, char *playlist, char *tag, char *searchstr, int maxentries, int timerange);
|
|
|
|
int mympd_smartpls_put(char *buffer, char *playlist);
|
2018-09-24 20:55:53 +00:00
|
|
|
int mympd_smartpls_update_all();
|
2018-09-24 22:27:24 +00:00
|
|
|
int mympd_smartpls_clear(char *playlist);
|
2018-11-29 18:00:50 +00:00
|
|
|
int mympd_smartpls_update_sticker(char *playlist, char *sticker, int maxentries);
|
2018-10-08 20:44:22 +00:00
|
|
|
int mympd_smartpls_update_newest(char *playlist, int timerange);
|
2018-09-26 22:10:51 +00:00
|
|
|
int mympd_smartpls_update_search(char *playlist, char *tag, char *searchstr);
|
2018-08-24 10:11:27 +00:00
|
|
|
int mympd_get_updatedb_state(char *buffer);
|
2018-10-18 22:23:58 +00:00
|
|
|
void mympd_get_song_uri_from_song_id(int song_id, char *uri);
|
2018-08-23 15:24:37 +00:00
|
|
|
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length);
|
2018-08-06 18:57:42 +00:00
|
|
|
int mympd_put_outputs(char *buffer);
|
2018-06-14 22:00:54 +00:00
|
|
|
int mympd_put_current_song(char *buffer);
|
2018-08-27 19:34:21 +00:00
|
|
|
int mympd_put_queue(char *buffer, unsigned int offset, unsigned *queue_version, unsigned *queue_length);
|
2018-06-14 22:00:54 +00:00
|
|
|
int mympd_put_browse(char *buffer, char *path, unsigned int offset, char *filter);
|
2018-09-03 18:02:12 +00:00
|
|
|
int mympd_search(char *buffer, char *searchstr, char *filter, char *plist, unsigned int offset);
|
2018-11-26 17:26:09 +00:00
|
|
|
int mympd_search_adv(char *buffer, char *expression, char *sort, bool sortdesc, char *grouptag, char *plist, unsigned int offset);
|
2018-06-14 22:00:54 +00:00
|
|
|
int mympd_search_queue(char *buffer, char *mpdtagtype, unsigned int offset, char *searchstr);
|
|
|
|
int mympd_put_welcome(char *buffer);
|
2018-10-11 19:50:26 +00:00
|
|
|
int mympd_put_volume(char *buffer);
|
2018-08-06 21:29:20 +00:00
|
|
|
int mympd_put_stats(char *buffer);
|
2018-05-29 21:05:34 +00:00
|
|
|
int mympd_put_settings(char *buffer);
|
2018-06-04 18:31:05 +00:00
|
|
|
int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char *mpdsearchtagtype, char *searchstr, char *filter);
|
2018-09-10 20:32:15 +00:00
|
|
|
int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag);
|
2018-06-04 18:31:05 +00:00
|
|
|
int mympd_put_playlists(char *buffer, unsigned int offset, char *filter);
|
2018-07-22 19:00:26 +00:00
|
|
|
int mympd_put_playlist_list(char *buffer, char *uri, unsigned int offset, char *filter);
|
2018-07-09 17:28:28 +00:00
|
|
|
int mympd_put_songdetails(char *buffer, char *uri);
|
2018-11-12 23:48:29 +00:00
|
|
|
int mympd_put_last_played_songs(char *buffer, unsigned int offset);
|
2018-08-05 22:02:29 +00:00
|
|
|
int mympd_queue_crop(char *buffer);
|
2018-06-14 22:00:54 +00:00
|
|
|
void mympd_disconnect();
|
2014-01-08 01:23:02 +00:00
|
|
|
#endif
|