mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-13 07:53:23 -05:00
add dmap methods to remotely add a playlist
This commit is contained in:
parent
de9d433b3e
commit
53f8c8166b
@ -46,6 +46,7 @@ typedef struct tag_db_functions {
|
||||
int(*dbs_init)(int);
|
||||
int(*dbs_deinit)(void);
|
||||
int(*dbs_add)(MP3FILE*);
|
||||
int(*dbs_add_playlist)(char *, int, char *, int *);
|
||||
int(*dbs_enum_start)(DBQUERYINFO *);
|
||||
int(*dbs_enum_size)(DBQUERYINFO *, int *);
|
||||
int(*dbs_enum_fetch)(DBQUERYINFO *, unsigned char **);
|
||||
@ -68,6 +69,7 @@ DB_FUNCTIONS db_functions[] = {
|
||||
db_sqlite_init,
|
||||
db_sqlite_deinit,
|
||||
db_sqlite_add,
|
||||
db_sqlite_add_playlist,
|
||||
db_sqlite_enum_start,
|
||||
db_sqlite_enum_size,
|
||||
db_sqlite_enum_fetch,
|
||||
@ -185,6 +187,7 @@ DAAP_ITEMS taglist[] = {
|
||||
/* mt-daapd specific */
|
||||
{ 0x09, "MSPS", "org.mt-daapd.smart-playlist-spec" },
|
||||
{ 0x01, "MPTY", "org.mt-daapd.playlist-type" },
|
||||
{ 0x0C, "MAPR", "org.mt-daapd.addplaylistresponse" },
|
||||
|
||||
{ 0x00, NULL, NULL }
|
||||
};
|
||||
@ -454,6 +457,27 @@ int db_add(MP3FILE *pmp3) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a playlist
|
||||
*
|
||||
* \param name name of playlist to add
|
||||
* \param type type of playlist to add: 0 - static, 1 - smart, 2 - m3u
|
||||
* \param clause where clause (if type 1)
|
||||
* \param playlistid returns the id of the playlist created
|
||||
* \returns 0 on success, error code otherwise
|
||||
*/
|
||||
int db_add_playlist(char *name, int type, char *clause, int *playlistid) {
|
||||
int retval;
|
||||
|
||||
db_writelock();
|
||||
retval=db_current->dbs_add_playlist(name,type,clause,playlistid);
|
||||
if(retval == DB_E_SUCCESS)
|
||||
db_revision_no++;
|
||||
db_unlock();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* start a db enumeration, based info in the DBQUERYINFO struct
|
||||
*
|
||||
|
@ -155,6 +155,8 @@ extern int db_end_scan(void);
|
||||
extern int db_exists(char *path);
|
||||
extern int db_scanning(void);
|
||||
|
||||
extern int db_add_playlist(char *name, int type, char *clause, int *playlistid);
|
||||
|
||||
extern MP3FILE *db_fetch_item(int id);
|
||||
extern MP3FILE *db_fetch_path(char *path);
|
||||
|
||||
@ -177,4 +179,12 @@ extern int db_get_song_count(void);
|
||||
extern int db_get_playlist_count(void);
|
||||
extern void db_dispose_item(MP3FILE *pmp3);
|
||||
|
||||
|
||||
#define DB_E_SUCCESS 0
|
||||
#define DB_E_SQL_ERROR 1 /**< some kind of sql error - typically bad syntax */
|
||||
#define DB_E_DUPLICATE_PLAYLIST 2 /**< playlist already exists when adding */
|
||||
#define DB_E_NOCLAUSE 3 /**< adding smart playlist with no clause */
|
||||
|
||||
|
||||
|
||||
#endif /* _DB_GENERIC_H_ */
|
||||
|
@ -53,7 +53,7 @@ void db_sqlite_build_mp3file(char **valarray, MP3FILE *pmp3);
|
||||
int db_sqlite_exec(int fatal, char *fmt, ...);
|
||||
int db_sqlite_get_table(int fatal, char ***resarray, int *rows, int *cols, char *fmt, ...);
|
||||
int db_sqlite_free_table(char **resarray);
|
||||
int db_sqlite_get_int(int loglevel, char *fmt, ...);
|
||||
int db_sqlite_get_int(int loglevel, int *result, char *fmt, ...);
|
||||
int db_sqlite_update(MP3FILE *pmp3);
|
||||
int db_sqlite_update_version(int from_version);
|
||||
int db_sqlite_get_version(void);
|
||||
@ -160,14 +160,13 @@ int db_sqlite_free_table(char **resarray) {
|
||||
/**
|
||||
* db_sqlite_get_int
|
||||
*/
|
||||
int db_sqlite_get_int(int loglevel, char *fmt, ...) {
|
||||
int db_sqlite_get_int(int loglevel, int *result, char *fmt, ...) {
|
||||
int rows, cols;
|
||||
char **resarray;
|
||||
va_list ap;
|
||||
char *query;
|
||||
int err;
|
||||
char *perr;
|
||||
int retval;
|
||||
|
||||
va_start(ap,fmt);
|
||||
query=sqlite_vmprintf(fmt,ap);
|
||||
@ -187,13 +186,13 @@ int db_sqlite_get_int(int loglevel, char *fmt, ...) {
|
||||
db_sqlite_lock();
|
||||
sqlite_freemem(query);
|
||||
db_sqlite_unlock();
|
||||
return 0;
|
||||
return DB_E_SQL_ERROR;
|
||||
}
|
||||
|
||||
retval=atoi(resarray[cols]);
|
||||
*result=atoi(resarray[cols]);
|
||||
|
||||
sqlite_free_table(resarray);
|
||||
return retval;
|
||||
return DB_E_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@ -224,10 +223,10 @@ int db_sqlite_open(char *parameters) {
|
||||
*/
|
||||
int db_sqlite_init(int reload) {
|
||||
int items;
|
||||
int rescan;
|
||||
int rescan=0;
|
||||
|
||||
db_sqlite_update_version(db_sqlite_get_version());
|
||||
rescan=db_sqlite_get_int(E_DBG,"SELECT value FROM config WHERE term='rescan'");
|
||||
db_sqlite_get_int(E_DBG,&rescan,"SELECT value FROM config WHERE term='rescan'");
|
||||
|
||||
if(rescan)
|
||||
reload=1;
|
||||
@ -298,6 +297,43 @@ int db_sqlite_end_scan(void) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* add a playlist
|
||||
*
|
||||
* \param name name of the playlist
|
||||
* \param type playlist type: 0 - static, 1 - smart, 2 - m3u
|
||||
* \param clause: "where" clause for smart playlist
|
||||
*/
|
||||
int db_sqlite_add_playlist(char *name, int type, char *clause, int *playlistid) {
|
||||
int cnt=0;
|
||||
int result;
|
||||
|
||||
db_sqlite_get_int(E_DBG,&cnt,"select count(*) from playlists where "
|
||||
"upper(title)=upper('%q')",name);
|
||||
|
||||
if(cnt) return DB_E_DUPLICATE_PLAYLIST;
|
||||
if((type == 1) && (!clause)) return DB_E_NOCLAUSE;
|
||||
|
||||
/* Let's throw it in */
|
||||
if(type == 1) {
|
||||
result=db_sqlite_get_int(E_DBG,&cnt,"select count (*) from songs where %s",clause);
|
||||
if(result != DB_E_SUCCESS) return result;
|
||||
result = db_sqlite_exec(E_LOG,"insert into playlists (title,smart,items,query) "
|
||||
"values ('%q',1,%d,'%q')",name,cnt,clause);
|
||||
} else {
|
||||
result = db_sqlite_exec(E_LOG,"insert into playlists (title,smart,items,query) "
|
||||
"values ('%q',0,0,NULL)",name);
|
||||
}
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = db_sqlite_get_int(E_LOG,playlistid,
|
||||
"select id from playlists where title='%q'", name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a database item
|
||||
*
|
||||
|
@ -37,5 +37,6 @@ extern int db_sqlite_get_count(CountType_t type);
|
||||
extern MP3FILE *db_sqlite_fetch_item(int id);
|
||||
extern MP3FILE *db_sqlite_fetch_path(char *path);
|
||||
extern void db_sqlite_dispose_item(MP3FILE *pmp3);
|
||||
extern int db_sqlite_add_playlist(char *name, int type, char *clause, int *playlistid);
|
||||
|
||||
#endif /* _DBS_SQLITE_H_ */
|
||||
|
@ -52,6 +52,7 @@ static void dispatch_playlistitems(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
static void dispatch_stream(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
static void dispatch_browse(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
static void dispatch_playlists(WS_CONNINFO *pqsc, DBQUERYINFO *pqi);
|
||||
static void dispatch_addplaylist(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
static void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
static void dispatch_logout(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
|
||||
@ -177,9 +178,11 @@ void daap_handler(WS_CONNINFO *pwsc) {
|
||||
}
|
||||
pqi->db_id=atoi(pqi->uri_sections[1]);
|
||||
if(pqi->uri_count == 3) {
|
||||
if(!strcasecmp(pqi->uri_sections[2],"items"))
|
||||
if(!strcasecmp(pqi->uri_sections[2],"items"))
|
||||
/* /databases/id/items */
|
||||
return dispatch_items(pwsc,pqi);
|
||||
if(!strcasecmp(pqi->uri_sections[2],"containers"))
|
||||
/* /databases/id/containers */
|
||||
return dispatch_playlists(pwsc,pqi);
|
||||
|
||||
pwsc->close=1;
|
||||
@ -189,9 +192,15 @@ void daap_handler(WS_CONNINFO *pwsc) {
|
||||
}
|
||||
if(pqi->uri_count == 4) {
|
||||
if(!strcasecmp(pqi->uri_sections[2],"browse"))
|
||||
/* /databases/id/browse/something */
|
||||
return dispatch_browse(pwsc,pqi);
|
||||
if(!strcasecmp(pqi->uri_sections[2],"items"))
|
||||
/* /databases/id/items/id.mp3 */
|
||||
return dispatch_stream(pwsc,pqi);
|
||||
if((!strcasecmp(pqi->uri_sections[2],"containers")) &&
|
||||
(!strcasecmp(pqi->uri_sections[3],"add")))
|
||||
/* /databases/id/containers/add */
|
||||
return dispatch_addplaylist(pwsc,pqi);
|
||||
|
||||
pwsc->close=1;
|
||||
free(pqi);
|
||||
@ -753,6 +762,51 @@ void dispatch_stream(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
||||
free(pqi);
|
||||
}
|
||||
|
||||
/**
|
||||
* add a playlist
|
||||
*/
|
||||
void dispatch_addplaylist(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
||||
char playlist_response[32];
|
||||
char *current=playlist_response;
|
||||
char *name, *query;
|
||||
int type;
|
||||
int retval, playlistid;
|
||||
|
||||
if((!ws_getvar(pwsc,"org.mt-daapd.playlist-type")) ||
|
||||
(!ws_getvar(pwsc,"dmap.itemname"))) {
|
||||
DPRINTF(E_LOG,L_DAAP,"attempt to add playlist with invalid type\n");
|
||||
ws_returnerror(pwsc,500,"bad playlist info specified");
|
||||
return;
|
||||
}
|
||||
|
||||
type=atoi(ws_getvar(pwsc,"org.mt-daapd.playlist-type"));
|
||||
name=ws_getvar(pwsc,"dmap.itemname");
|
||||
query=ws_getvar(pwsc,"org.mt-daapd.smart-playlist-spec");
|
||||
|
||||
retval=db_add_playlist(name,type,query,&playlistid);
|
||||
if(retval != DB_E_SUCCESS) {
|
||||
DPRINTF(E_LOG,L_DAAP,"error adding playlist. aborting\n");
|
||||
ws_returnerror(pwsc,500,"error adding playlist");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success... spool out a dmap block */
|
||||
current += db_dmap_add_container(current,"MAPR",24);
|
||||
current += db_dmap_add_int(current,"mstt",200); /* 12 */
|
||||
current += db_dmap_add_int(current,"miid",playlistid); /* 12 */
|
||||
|
||||
dispatch_output_start(pwsc,pqi,32);
|
||||
dispatch_output_write(pwsc,pqi,playlist_response,32);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
|
||||
pwsc->close=1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerate and return playlistitems
|
||||
*/
|
||||
void dispatch_playlistitems(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
||||
char items_response[61];
|
||||
char *current=items_response;
|
||||
|
Loading…
Reference in New Issue
Block a user