From 33e6284639d7c5c743de2ca7a181c386021d0a8f Mon Sep 17 00:00:00 2001 From: Ron Pedde Date: Sat, 2 Apr 2005 10:52:28 +0000 Subject: [PATCH] Add daap functions to add items to a static playlist --- src/db-generic.c | 26 +++++++++++++++++++++++-- src/db-generic.h | 7 +++++-- src/dbs-sqlite.c | 44 ++++++++++++++++++++++++++++++++++++++++++ src/dbs-sqlite.h | 1 + src/dispatch.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 4 deletions(-) diff --git a/src/db-generic.c b/src/db-generic.c index 392099d1..e992d7d7 100644 --- a/src/db-generic.c +++ b/src/db-generic.c @@ -47,6 +47,7 @@ typedef struct tag_db_functions { int(*dbs_deinit)(void); int(*dbs_add)(MP3FILE*); int(*dbs_add_playlist)(char *, int, char *, int *); + int(*dbs_add_playlist_item)(int, int); int(*dbs_enum_start)(DBQUERYINFO *); int(*dbs_enum_size)(DBQUERYINFO *, int *); int(*dbs_enum_fetch)(DBQUERYINFO *, unsigned char **); @@ -70,6 +71,7 @@ DB_FUNCTIONS db_functions[] = { db_sqlite_deinit, db_sqlite_add, db_sqlite_add_playlist, + db_sqlite_add_playlist_item, db_sqlite_enum_start, db_sqlite_enum_size, db_sqlite_enum_fetch, @@ -187,8 +189,8 @@ 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" }, - + { 0x0C, "MAPR", "org.mt-daapd.addplaylist" }, + { 0x0C, "MAPI", "org.mt-daapd.addplaylistitem" }, { 0x00, NULL, NULL } }; @@ -478,6 +480,26 @@ int db_add_playlist(char *name, int type, char *clause, int *playlistid) { return retval; } +/** + * add a song to a static playlist + * + * \param playlistid playlist to add song to + * \param songid song to add to playlist + * \returns 0 on success, DB_E_ code otherwise + */ +int db_add_playlist_item(int playlistid, int songid) { + int retval; + + db_writelock(); + retval=db_current->dbs_add_playlist_item(playlistid,songid); + if(retval == DB_E_SUCCESS) + db_revision_no++; + db_unlock(); + + return retval; +} + + /** * start a db enumeration, based info in the DBQUERYINFO struct * diff --git a/src/db-generic.h b/src/db-generic.h index c603282b..a7a8e0a4 100644 --- a/src/db-generic.h +++ b/src/db-generic.h @@ -156,6 +156,7 @@ 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 int db_add_playlist_item(int playlistid, int songid); extern MP3FILE *db_fetch_item(int id); extern MP3FILE *db_fetch_path(char *path); @@ -184,7 +185,9 @@ extern void db_dispose_item(MP3FILE *pmp3); #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 */ - - +#define DB_E_INVALIDTYPE 4 /**< trying to add playlist items to invalid type */ +#define DB_E_NOROWS 5 /**< sql query returned no rows */ +#define DB_E_INVALID_PLAYLIST 6 /**< bad playlist id */ +#define DB_E_INVALID_SONGID 7 /**< bad song id */ #endif /* _DB_GENERIC_H_ */ diff --git a/src/dbs-sqlite.c b/src/dbs-sqlite.c index 0038914f..46ded559 100644 --- a/src/dbs-sqlite.c +++ b/src/dbs-sqlite.c @@ -189,6 +189,11 @@ int db_sqlite_get_int(int loglevel, int *result, char *fmt, ...) { return DB_E_SQL_ERROR; } + if(rows==0) { + sqlite_free_table(resarray); + return DB_E_NOROWS; + } + *result=atoi(resarray[cols]); sqlite_free_table(resarray); @@ -334,6 +339,45 @@ int db_sqlite_add_playlist(char *name, int type, char *clause, int *playlistid) return result; } +/** + * add a song to a static playlist + * + * \param playlistid playlist to add song to + * \param songid song to add + * \returns 0 on success, otherwise a DB_E error code + */ +int db_sqlite_add_playlist_item(int playlistid, int songid) { + int result; + int playlist_type; + int count; + + /* first, check the playlist */ + result=db_sqlite_get_int(E_DBG,&playlist_type, + "select smart from playlists where id=%d",playlistid); + + if(result != DB_E_SUCCESS) { + if(result == DB_E_NOROWS) + return DB_E_INVALID_PLAYLIST; + return result; + } + + if(playlist_type == 1) /* can't add to smart playlists */ + return DB_E_INVALIDTYPE; + + /* make sure the songid is valid */ + result=db_sqlite_get_int(E_DBG,&count,"select count(*) from songs where id=%d",songid); + if(result != DB_E_SUCCESS) { + if(result == DB_E_NOROWS) + return DB_E_INVALID_SONGID; + return result; + } + + /* looks valid, so lets add the item */ + result=db_sqlite_exec(E_DBG,"insert into playlistitems values (%d,%d)",playlistid,songid); + return result; +} + + /** * add a database item * diff --git a/src/dbs-sqlite.h b/src/dbs-sqlite.h index 117f4408..a4732bb6 100644 --- a/src/dbs-sqlite.h +++ b/src/dbs-sqlite.h @@ -38,5 +38,6 @@ 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); +extern int db_sqlite_add_playlist_item(int playlistid, int songid); #endif /* _DBS_SQLITE_H_ */ diff --git a/src/dispatch.c b/src/dispatch.c index 74fee3cc..d4cc8961 100644 --- a/src/dispatch.c +++ b/src/dispatch.c @@ -53,6 +53,7 @@ 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_addplaylistitems(WS_CONNINFO *pwsc, DBQUERYINFO *pqi); static void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi); static void dispatch_logout(WS_CONNINFO *pwsc, DBQUERYINFO *pqi); @@ -214,6 +215,14 @@ void daap_handler(WS_CONNINFO *pwsc) { return dispatch_playlistitems(pwsc,pqi); } } + if(pqi->uri_count == 6) { + if((!strcasecmp(pqi->uri_sections[2],"containers")) && + (!strcasecmp(pqi->uri_sections[4],"items")) && + (!strcasecmp(pqi->uri_sections[5],"add"))) { + pqi->playlist_id=atoi(pqi->uri_sections[3]); + return dispatch_addplaylistitems(pwsc,pqi); + } + } } pwsc->close=1; @@ -762,6 +771,47 @@ void dispatch_stream(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) { free(pqi); } + +/** + * add songs to an existing playlist + */ +void dispatch_addplaylistitems(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) { + char playlist_response[20]; + char *current; + char *tempstring; + char *token; + + if(!ws_getvar(pwsc,"dmap.itemid")) { + DPRINTF(E_LOG,L_DAAP,"attempt to add playlist items with no dmap.itemid\n"); + ws_returnerror(pwsc,500,"no itemid specified"); + return; + } + + tempstring=strdup(ws_getvar(pwsc,"dmap.itemid")); + current=tempstring; + + while((token=strsep(¤t,","))) { + if(token) { + db_add_playlist_item(pqi->playlist_id,atoi(token)); + } + } + + free(tempstring); + + /* success(ish)... spool out a dmap block */ + current = playlist_response; + current += db_dmap_add_container(current,"MAPI",12); + current += db_dmap_add_int(current,"mstt",200); /* 12 */ + + dispatch_output_start(pwsc,pqi,20); + dispatch_output_write(pwsc,pqi,playlist_response,20); + dispatch_output_end(pwsc,pqi); + + pwsc->close=1; + + return; +} + /** * add a playlist */