diff --git a/NEWS b/NEWS index b56092f..a0872f5 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ 1.0.22 - Released 00-Month-0000 -------------------------------- -- Add thumbnail support on folders, since at least XBMC supports it. +- Add bookmark support for Samsung TV's. 1.0.21 - Released 18-July-2011 -------------------------------- diff --git a/minidlna.c b/minidlna.c index 6798ffc..1ce0d52 100644 --- a/minidlna.c +++ b/minidlna.c @@ -871,7 +871,6 @@ main(int argc, char * * argv) time_t lastupdatetime = 0; int max_fd = -1; int last_changecnt = 0; - short int new_db = 0; pid_t scanner_pid = 0; pthread_t inotify_thread = 0; struct media_dir_s *media_path, *last_path; @@ -911,14 +910,14 @@ main(int argc, char * * argv) #endif LIST_INIT(&upnphttphead); - new_db = open_db(); - if( !new_db ) + if( open_db() == 0 ) { updateID = sql_get_int_field(db, "SELECT UPDATE_ID from SETTINGS"); } - if( sql_get_int_field(db, "pragma user_version") != DB_VERSION ) + i = db_upgrade(db); + if( i != 0 ) { - if( new_db ) + if( i < 0 ) { DPRINTF(E_WARN, L_GENERAL, "Creating new database...\n"); } diff --git a/scanner.c b/scanner.c index 3a6f775..594d9d9 100644 --- a/scanner.c +++ b/scanner.c @@ -606,6 +606,12 @@ CreateDatabase(void) ")"); if( ret != SQLITE_OK ) goto sql_failed; + ret = sql_exec(db, "CREATE TABLE BOOKMARKS (" + "ID INTEGER PRIMARY KEY, " + "SEC INTEGER" + ")"); + if( ret != SQLITE_OK ) + goto sql_failed; ret = sql_exec(db, "CREATE TABLE PLAYLISTS (" "ID INTEGER PRIMARY KEY AUTOINCREMENT, " "NAME TEXT NOT NULL, " diff --git a/sql.c b/sql.c index 6311e1e..e8bdebd 100644 --- a/sql.c +++ b/sql.c @@ -20,6 +20,7 @@ #include #include "sql.h" +#include "upnpglobalvars.h" #include "log.h" int @@ -124,7 +125,7 @@ sql_get_int_field(sqlite3 *db, const char *fmt, ...) } char * -sql_get_text_field(void *db, const char *fmt, ...) +sql_get_text_field(sqlite3 *db, const char *fmt, ...) { va_list ap; int counter, result, len; @@ -198,3 +199,31 @@ sql_get_text_field(void *db, const char *fmt, ...) sqlite3_finalize(stmt); return str; } + +int +db_upgrade(sqlite3 *db) +{ + int db_vers; + int ret; + + db_vers = sql_get_int_field(db, "PRAGMA user_version"); + + if (db_vers == DB_VERSION) + return 0; + if (db_vers < 1) + return -1; + if (db_vers < 5) + return 5; + if (db_vers < 6) + { + DPRINTF(E_WARN, L_DB_SQL, "Updating DB version to v%d.\n", DB_VERSION); + ret = sql_exec(db, "CREATE TABLE BOOKMARKS (" + "ID INTEGER PRIMARY KEY, " + "SEC INTEGER)"); + if( ret != SQLITE_OK ) + return 6; + } + sql_exec(db, "PRAGMA user_version = %d", DB_VERSION); + + return 0; +} diff --git a/sql.h b/sql.h index e2e9661..b3742ca 100644 --- a/sql.h +++ b/sql.h @@ -36,6 +36,9 @@ int sql_get_int_field(sqlite3 *db, const char *fmt, ...); char * -sql_get_text_field(void *dbh, const char *fmt, ...); +sql_get_text_field(sqlite3 *db, const char *fmt, ...); + +int +db_upgrade(sqlite3 *db); #endif diff --git a/upnpglobalvars.h b/upnpglobalvars.h index 34648be..5fac5f1 100644 --- a/upnpglobalvars.h +++ b/upnpglobalvars.h @@ -66,7 +66,7 @@ #define CLIENT_CACHE_SLOTS 20 #define USE_FORK 1 -#define DB_VERSION 5 +#define DB_VERSION 6 #ifdef ENABLE_NLS #define _(string) gettext(string) diff --git a/upnpsoap.c b/upnpsoap.c index 42df6a3..77627c3 100644 --- a/upnpsoap.c +++ b/upnpsoap.c @@ -344,6 +344,9 @@ mime_to_ext(const char * mime, char * buf) #define FILTER_UPNP_GENRE 0x00040000 #define FILTER_UPNP_ORIGINALTRACKNUMBER 0x00080000 #define FILTER_UPNP_SEARCHCLASS 0x00100000 +#define FILTER_SEC 0x00200000 +#define FILTER_SEC_CAPTION_INFO 0x00400000 +#define FILTER_SEC_CAPTION_INFO_EX 0x00800000 static u_int32_t set_filter_flags(char * filter, struct upnphttp *h) @@ -467,6 +470,16 @@ set_filter_flags(char * filter, struct upnphttp *h) flags |= FILTER_RES; flags |= FILTER_RES_SIZE; } + else if( strcmp(item, "sec:CaptionInfo") == 0) + { + flags |= FILTER_SEC; + flags |= FILTER_SEC_CAPTION_INFO; + } + else if( strcmp(item, "sec:CaptionInfoEx") == 0) + { + flags |= FILTER_SEC; + flags |= FILTER_SEC_CAPTION_INFO_EX; + } item = strtok_r(NULL, ",", &saveptr); } @@ -742,6 +755,11 @@ callback(void *args, int argc, char **argv, char **azColName) if( date && (passed_args->filter & FILTER_DC_DATE) ) { ret = strcatf(str, "<dc:date>%s</dc:date>", date); } + if( passed_args->filter & FILTER_SEC_CAPTION_INFO_EX) { + /* Get bookmark */ + ret = strcatf(str, "<sec:dcmInfo>CREATIONDATE=0,FOLDER=%s,BM=%d</sec:dcmInfo>", + title, sql_get_int_field(db, "SELECT SEC from BOOKMARKS where ID = '%s'", detailID)); + } if( artist ) { if( (*mime == 'v') && (passed_args->filter & FILTER_UPNP_ACTOR) ) { ret = strcatf(str, "<upnp:actor>%s</upnp:actor>", artist); @@ -1440,7 +1458,37 @@ SamsungGetFeatureList(struct upnphttp * h, const char * action) "</Feature>" ""; - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)); + BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); +} + +static void +SamsungSetBookmark(struct upnphttp * h, const char * action) +{ + static const char resp[] = + "" + ""; + + struct NameValueParserData data; + char *ObjectID, *PosSecond; + int ret; + + ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); + ObjectID = GetValueFromNameValueList(&data, "ObjectID"); + PosSecond = GetValueFromNameValueList(&data, "PosSecond"); + if( ObjectID && PosSecond ) + { + ret = sql_exec(db, "INSERT OR REPLACE into BOOKMARKS" + " VALUES " + "((select DETAIL_ID from OBJECTS where OBJECT_ID = '%s'), %s)", ObjectID, PosSecond); + if( ret != SQLITE_OK ) + DPRINTF(E_WARN, L_METADATA, "Error setting bookmark %s on ObjectID='%s'\n", PosSecond, ObjectID); + BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + } + else + SoapError(h, 402, "Invalid Args"); + + ClearNameValueList(&data); } static const struct @@ -1462,6 +1510,7 @@ soapMethods[] = { "IsAuthorized", IsAuthorizedValidated}, { "IsValidated", IsAuthorizedValidated}, { "X_GetFeatureList", SamsungGetFeatureList}, + { "X_SetBookmark", SamsungSetBookmark}, { 0, 0 } };