diff options
author | methodus <methodus@web.de> | 2012-09-15 23:44:19 +0200 |
---|---|---|
committer | methodus <methodus@web.de> | 2012-09-15 23:44:19 +0200 |
commit | 159592eaa3b7ba9135bf01b4015af0d7914805bf (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /database | |
parent | 15139183fdea8f65af5a7dbfd354bcedf5886e80 (diff) | |
download | vdr-plugin-upnp-159592eaa3b7ba9135bf01b4015af0d7914805bf.tar.gz vdr-plugin-upnp-159592eaa3b7ba9135bf01b4015af0d7914805bf.tar.bz2 |
Master geleert
Diffstat (limited to 'database')
-rw-r--r-- | database/database.cpp | 300 | ||||
-rw-r--r-- | database/metadata.cpp | 575 | ||||
-rw-r--r-- | database/object.cpp | 1887 | ||||
-rw-r--r-- | database/resources.cpp | 355 |
4 files changed, 0 insertions, 3117 deletions
diff --git a/database/database.cpp b/database/database.cpp deleted file mode 100644 index c58294d..0000000 --- a/database/database.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* - * File: database.h - * Author: savop - * - * Created on 3. September 2009, 22:20 - */ - -#include <string.h> -#include <stdlib.h> -#include <sqlite3.h> -#include "database.h" -#include "../common.h" -#include "object.h" -#include "../upnp.h" -#include "config.h" - -cSQLiteDatabase* cSQLiteDatabase::mInstance = NULL; - -cSQLiteDatabase::cSQLiteDatabase(){ - this->mActiveTransaction = false; - this->mDatabase = NULL; - this->mLastRow = NULL; - this->mRows = NULL; -} - -cSQLiteDatabase::~cSQLiteDatabase(){ - sqlite3_close(this->mDatabase); -} - -cSQLiteDatabase* cSQLiteDatabase::getInstance(){ - if(cSQLiteDatabase::mInstance == NULL){ - cSQLiteDatabase::mInstance = new cSQLiteDatabase; - DatabaseLocker.Wait(); - cSQLiteDatabase::mInstance->initialize(); - } - - if(cSQLiteDatabase::mInstance != NULL) - return cSQLiteDatabase::mInstance; - else - return NULL; -} - -int cSQLiteDatabase::exec(const char* Statement){ - char* Error; - if(!this->mDatabase){ - ERROR("Database not open. Cannot continue"); - return -1; - } - this->mRows = new cRows; - MESSAGE(VERBOSE_SQL_STATEMENTS,"SQLite: %s", Statement); - if(sqlite3_exec(this->mDatabase, Statement, cSQLiteDatabase::getResultRow, (cSQLiteDatabase*)this, &Error)!=SQLITE_OK){ - ERROR("Database error: %s", Error); - ERROR("Statement was: %s", Statement); - delete this->mRows; this->mRows = NULL; - sqlite3_free(Error); - return -1; - } - - sqlite3_free(Error); - return 0; -} - -const char* cSQLiteDatabase::sprintf(const char* Format, ...){ - va_list vlist; - va_start(vlist, Format); - char* SQLStatement = sqlite3_vmprintf(Format, vlist); - va_end(vlist); - return SQLStatement; -} - -int cSQLiteDatabase::execStatement(const char* Statement, ...){ - va_list vlist; - va_start(vlist, Statement); - char* SQLStatement = sqlite3_vmprintf(Statement, vlist); - va_end(vlist); - int ret = this->exec(SQLStatement); - sqlite3_free(SQLStatement); - return ret; -} - -int cSQLiteDatabase::getResultRow(void* DB, int NumCols, char** Values, char** ColNames){ - cRow* Row = new cRow; - Row->ColCount = NumCols; - Row->Columns = new char*[NumCols]; - Row->Values = new char*[NumCols]; - for(int i=0; i < NumCols; i++){ - Row->Columns[i] = strdup0(ColNames[i]); - Row->Values[i] = strdup0(Values[i]); - } - cSQLiteDatabase* Database = (cSQLiteDatabase*)DB; - Database->mRows->Add(Row); - return 0; -} - -cRows::cRows(){ - this->mLastRow = NULL; -} - -cRows::~cRows(){ - this->mLastRow = NULL; -} - -bool cRows::fetchRow(cRow** Row){ - if(this->mLastRow==NULL){ - this->mLastRow = this->First(); - } - else { - this->mLastRow = this->Next(this->mLastRow); - } - if(this->mLastRow != NULL){ - *Row = this->mLastRow; - return true; - } - else { - *Row = NULL; - return false; - } - return false; -} - -cRow::cRow(){ - this->currentCol = 0; - this->ColCount = 0; - this->Columns = NULL; - this->Values = NULL; -} - -cRow::~cRow(){ - delete [] this->Columns; - delete [] this->Values; - this->Columns = NULL; - this->Values = NULL; -} - -bool cRow::fetchColumn(cString* Column, cString* Value){ - char *Col, *Val; - bool ret = this->fetchColumn(&Col, &Val); - if(ret){ - *Column = cString(Col,true); - *Value = cString(Val,true); - } - return ret; -} - - -bool cRow::fetchColumn(char** Column, char** Value){ - if(currentCol>=this->ColCount){ - return false; - } - MESSAGE(VERBOSE_SQL_FETCHES,"Fetching column %s='%s' (%d/%d)", this->Columns[currentCol], this->Values[currentCol], currentCol+1, this->ColCount); - *Column = strdup0(this->Columns[currentCol]); - if(this->Values[currentCol]){ - *Value = strcasecmp(this->Values[currentCol],"NULL")?strdup(this->Values[currentCol]):NULL; - } - else { - *Value = NULL; - } - currentCol++; - return true; -} - -int cSQLiteDatabase::initialize(){ - int ret; - const char* dbdir = (cUPnPConfig::get()->mDatabaseFolder) ? cUPnPConfig::get()->mDatabaseFolder : cPluginUpnp::getConfigDirectory(); - cString File = cString::sprintf("%s/%s", dbdir, SQLITE_DB_FILE); - if((ret = sqlite3_open(File, &this->mDatabase))){ - ERROR("Unable to open database file %s (Error code: %d)!", *File, ret); - sqlite3_close(this->mDatabase); - return -1; - } - MESSAGE(VERBOSE_SDK,"Database file %s opened.", *File); - if(this->initializeTables()){ - ERROR("Error while creating tables"); - return -1; - } - else if(this->initializeTriggers()){ - ERROR("Error while setting triggers"); - return -1; - } - return 0; -} - -void cSQLiteDatabase::startTransaction(){ - if(this->mActiveTransaction){ - if(this->mAutoCommit){ - this->commitTransaction(); - } - else { - this->rollbackTransaction(); - } - } - this->execStatement("BEGIN TRANSACTION"); - MESSAGE(VERBOSE_SQL,"Start new transaction"); - this->mActiveTransaction = true; -} - -void cSQLiteDatabase::commitTransaction(){ - this->execStatement("COMMIT TRANSACTION"); - MESSAGE(VERBOSE_SQL,"Commited transaction"); - this->mActiveTransaction = false; -} - -void cSQLiteDatabase::rollbackTransaction(){ - this->execStatement("ROLLBACK TRANSACTION"); - MESSAGE(VERBOSE_SQL,"Rolled back transaction"); - this->mActiveTransaction = false; -} - -int cSQLiteDatabase::initializeTables(){ - int ret = 0; - this->startTransaction(); - if(this->execStatement(SQLITE_CREATE_TABLE_ITEMFINDER)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_SYSTEM)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_PRIMARY_KEYS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_ALBUMS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_AUDIOBROADCASTS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_AUDIOITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_CONTAINER)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_IMAGEITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_ITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_MOVIES)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_OBJECTS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_PHOTOS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_PLAYLISTS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_RESOURCES)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_SEARCHCLASS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_VIDEOBROADCASTS)==-1) ret = -1; - if(this->execStatement(SQLITE_CREATE_TABLE_VIDEOITEMS)==-1) ret = -1; - if(ret){ - this->rollbackTransaction(); - } - else { - this->commitTransaction(); - } - return ret; -} - -int cSQLiteDatabase::initializeTriggers(){ - int ret = 0; - this->startTransaction(); - if(this->execStatement(SQLITE_TRIGGER_D_OBJECTS_ITEMFINDER)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_UPDATE_SYSTEM)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_UPDATE_OBJECTID)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_AUDIOITEMS_AUDIOBROADCASTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_CONTAINERS_ALBUMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_CONTAINERS_PLAYLISTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_CONTAINERS_SEARCHCLASSES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_IMAGEITEMS_PHOTOS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_ITEMS_AUDIOITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_ITEMS_IMAGEITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_ITEMS_ITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_ITEMS_VIDEOITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_OBJECTS_OBJECTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_OBJECT_CONTAINERS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_OBJECT_ITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_OBJECT_RESOURCES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_VIDEOITEMS_MOVIES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_D_VIDEOITEMS_VIDEOBROADCASTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_AUDIOITEMS_AUDIOBROADCASTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_CONTAINERS_ALBUMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_CONTAINERS_PLAYLISTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_CONTAINERS_SEARCHCLASSES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_IMAGEITEMS_PHOTOS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_ITEMS_AUDIOITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_ITEMS_IMAGEITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_ITEMS_ITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_ITEMS_VIDEOITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_OBJECTS_OBJECTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_OBJECT_CONTAINERS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_OBJECT_ITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_OBJECT_RESOURCES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_VIDEOITEMS_MOVIES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_I_VIDEOITEMS_VIDEOBROADCASTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_AUDIOITEMS_AUDIOBROADCASTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_CONTAINERS_ALBUMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_CONTAINERS_PLAYLISTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_CONTAINERS_SEARCHCLASSES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_IMAGEITEMS_PHOTOS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_ITEMS_AUDIOITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_ITEMS_IMAGEITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_ITEMS_ITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_ITEMS_VIDEOITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_OBJECTS_OBJECTS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_OBJECT_CONTAINERS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_OBJECT_ITEMS)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_OBJECT_RESOURCES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_VIDEOITEMS_MOVIES)==-1) ret = -1; - if(this->execStatement(SQLITE_TRIGGER_U_VIDEOITEMS_VIDEOBROADCASTS)==-1) ret = -1; - if(ret){ - this->rollbackTransaction(); - } - else { - this->commitTransaction(); - } - return ret; -} - -long cSQLiteDatabase::getLastInsertRowID() const { - return (long)sqlite3_last_insert_rowid(this->mDatabase); -}
\ No newline at end of file diff --git a/database/metadata.cpp b/database/metadata.cpp deleted file mode 100644 index a9d780f..0000000 --- a/database/metadata.cpp +++ /dev/null @@ -1,575 +0,0 @@ -/* - * File: metadata.cpp - * Author: savop - * - * Created on 28. Mai 2009, 16:50 - */ - -#include <upnp/ixml.h> -#include <time.h> -#include <vdr/tools.h> -#include "object.h" -#include "resources.h" -#include "metadata.h" -#include "../common.h" -#include "search.h" -#include <vdr/channels.h> -#include <vdr/epg.h> -#include <upnp/upnp.h> -#include <vdr/device.h> - -#define KEY_SYSTEM_UPDATE_ID "SystemUpdateID" - - /**********************************************\ - * * - * Media database * - * * - \**********************************************/ - -cMediaDatabase::cMediaDatabase(){ - this->mSystemUpdateID = 0; - this->mLastInsertObjectID = 0; - this->mDatabase = cSQLiteDatabase::getInstance(); - this->mObjects = new cHash<cUPnPClassObject>; - this->mFactory = cUPnPObjectFactory::getInstance(); - this->mFactory->registerMediator(UPNP_CLASS_ITEM, new cUPnPItemMediator(this)); - this->mFactory->registerMediator(UPNP_CLASS_CONTAINER, new cUPnPContainerMediator(this)); - this->mFactory->registerMediator(UPNP_CLASS_VIDEO, new cUPnPVideoItemMediator(this)); - this->mFactory->registerMediator(UPNP_CLASS_VIDEOBC, new cUPnPVideoBroadcastMediator(this)); - this->mFactory->registerMediator(UPNP_CLASS_MOVIE, new cUPnPMovieMediator(this)); -} - -cMediaDatabase::~cMediaDatabase(){ - delete this->mDatabase; -} - -bool cMediaDatabase::init(){ - MESSAGE(VERBOSE_SDK,"Initializing..."); - if(this->prepareDatabase()){ - ERROR("Initializing of database failed."); - return false; - } -#ifndef WITHOUT_TV - if(this->loadChannels()){ - ERROR("Loading channels failed"); - return false; - } -#endif -#ifndef WITHOUT_RECORDS - if(this->loadRecordings()){ - ERROR("Loading records failed"); - return false; - } -#endif - return true; -} - -void cMediaDatabase::updateSystemID(){ - this->mDatabase->execStatement("INSERT OR REPLACE INTO %s (Key,Value) VALUES (%Q,%d)", - SQLITE_TABLE_SYSTEM, - KEY_SYSTEM_UPDATE_ID, - this->getSystemUpdateID()+1); -} - -const char* cMediaDatabase::getContainerUpdateIDs(){ - return ""; -} - -unsigned int cMediaDatabase::getSystemUpdateID(){ - if(this->mDatabase->execStatement("SELECT Value FROM %s WHERE Key=%Q", - SQLITE_TABLE_SYSTEM, - KEY_SYSTEM_UPDATE_ID)){ - ERROR("Error while executing statement"); - return 0; - } - cRows* Rows = this->mDatabase->getResultRows(); - cRow* Row; - cString Column, Value; - if(!Rows->fetchRow(&Row)){ - ERROR("No rows found"); - return 0; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, "Value")){ - this->mSystemUpdateID = (unsigned int)atoi(Value); - } - } - return this->mSystemUpdateID; -} - -cUPnPObjectID cMediaDatabase::getNextObjectID(){ - cString Column, Value; - if(this->mDatabase->execStatement("SELECT Key FROM %s WHERE KeyID=%Q", - SQLITE_TABLE_PRIMARY_KEYS, - PK_OBJECTS)){ - ERROR("Error while executing statement"); - return 0; - } - cRows* Rows = this->mDatabase->getResultRows(); - cRow* Row; - int ret = 0; - if(!Rows->fetchRow(&Row)){ - ERROR("No rows found"); - ret = 0; - } - else { - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, "Key")){ - this->mLastInsertObjectID = atoi(Value); - ret = this->mLastInsertObjectID; - } - } - } - delete Rows; - return ret; -} - -int cMediaDatabase::addFastFind(cUPnPClassObject* Object, const char* FastFind){ - if(!Object || !FastFind){ - MESSAGE(VERBOSE_OBJECTS,"Invalid fast find parameters"); - return -1; - } - - if(this->mDatabase->execStatement("INSERT OR REPLACE INTO %s (%s, %s) VALUES (%Q, %Q)", - SQLITE_TABLE_ITEMFINDER, - SQLITE_COL_OBJECTID, - SQLITE_COL_ITEMFINDER, - *Object->getID(), - FastFind)){ - ERROR("Error while executing statement"); - return -1; - } - return 0; -} - -cUPnPClassObject* cMediaDatabase::getObjectByFastFind(const char* FastFind){ - if(!FastFind) return NULL; - MESSAGE(VERBOSE_OBJECTS,"Try to find Object with identifier %s", FastFind); - cString Column, Value; - if(this->mDatabase->execStatement("SELECT %s FROM %s WHERE %s=%Q", - SQLITE_COL_OBJECTID, - SQLITE_TABLE_ITEMFINDER, - SQLITE_COL_ITEMFINDER, - FastFind)){ - ERROR("Error while executing statement"); - return 0; - } - cRows* Rows = this->mDatabase->getResultRows(); - cRow* Row; - if(!Rows->fetchRow(&Row)){ - ERROR("No rows found"); - return NULL; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_OBJECTID)){ - return this->getObjectByID(atoi(Value)); - } - } - delete Rows; - return NULL; -} - -cUPnPClassObject* cMediaDatabase::getObjectByID(cUPnPObjectID ID){ - MESSAGE(VERBOSE_OBJECTS, "Try to find Object with ID '%s'", *ID); - cUPnPClassObject* Object; - if((Object = this->mObjects->Get((unsigned int)ID))){ - MESSAGE(VERBOSE_OBJECTS, "Found cached object with ID '%s'", *ID); - } - else if((Object = this->mFactory->getObject(ID))){ - //this->cacheObject(Object); - MESSAGE(VERBOSE_OBJECTS, "Found object with ID '%s' in database", *ID); - } - else { - ERROR("No object with such ID '%s'", *ID); - return NULL; - } - return Object; -} - -void cMediaDatabase::cacheObject(cUPnPClassObject* Object){ - if(this->mObjects->Get((unsigned int)Object->getID())==NULL){ - MESSAGE(VERBOSE_OBJECTS ,"Added %s to cache.", *Object->getID()); - this->mObjects->Add(Object, (unsigned int)Object->getID()); - } -} - -int cMediaDatabase::prepareDatabase(){ - if(this->getObjectByID(0)==NULL){ - MESSAGE(VERBOSE_SDK, "Creating database structure"); - cUPnPClassContainer* Root = (cUPnPClassContainer*)this->mFactory->createObject(UPNP_CLASS_CONTAINER, _(PLUGIN_SHORT_NAME)); - Root->setID(0); - if(this->mFactory->saveObject(Root)) return -1; - -#ifndef WITHOUT_VIDEO - cUPnPClassContainer* Video = (cUPnPClassContainer*)this->mFactory->createObject(UPNP_CLASS_CONTAINER, _("Video")); - Video->setID(1); - Root->addObject(Video); - cClass VideoClass = { UPNP_CLASS_VIDEO, true }; - Video->addSearchClass(VideoClass); - Video->setSearchable(true); - if(this->mFactory->saveObject(Video)) return -1; -#endif -#ifndef WITHOUT_AUDIO - cUPnPClassContainer* Audio = (cUPnPClassContainer*)this->mFactory->createObject(UPNP_CLASS_CONTAINER, _("Audio")); - Audio->setID(2); - Root->addObject(Audio); - cClass AudioClass = { UPNP_CLASS_AUDIO, true }; - Audio->addSearchClass(AudioClass); - Audio->setSearchable(true); - if(this->mFactory->saveObject(Audio)) return -1; -#endif -#ifndef WITHOUT_TV - cUPnPClassContainer* TV = (cUPnPClassContainer*)this->mFactory->createObject(UPNP_CLASS_CONTAINER, _("TV")); - TV->setID(3); - TV->setContainerType(DLNA_CONTAINER_TUNER); - TV->setSearchable(true); - cClass VideoBCClass = { UPNP_CLASS_VIDEOBC, true }; - TV->addSearchClass(VideoBCClass); - Video->addObject(TV); - if(this->mFactory->saveObject(TV)) return -1; -#endif -#ifndef WITHOUT_RECORDS - cUPnPClassContainer* Records = (cUPnPClassContainer*)this->mFactory->createObject(UPNP_CLASS_CONTAINER, _("Records")); - Records->setID(4); - Video->addObject(Records); - Records->addSearchClass(VideoClass); - Records->setSearchable(true); - if(this->mFactory->saveObject(Records)) return -1; -#endif -#ifndef WITHOUT_RADIO - cUPnPClassContainer* Radio = (cUPnPClassContainer*)this->mFactory->createObject(UPNP_CLASS_CONTAINER, _("Radio")); - Radio->setID(5); - Audio->addObject(Radio); - cClass AudioBCClass = { UPNP_CLASS_AUDIOBC, true }; - Radio->addSearchClass(AudioBCClass); - Radio->setSearchable(true); - if(this->mFactory->saveObject(Radio)) return -1; -#endif -#ifndef WITHOUT_CUSTOM_VIDEOS - cUPnPClassContainer* CustomVideos = (cUPnPClassContainer*)this->mFactory->createObject(UPNP_CLASS_CONTAINER, _("User videos")); - CustomVideos->setID(6); - Video->addObject(CustomVideos); - CustomVideos->addSearchClass(VideoClass); - CustomVideos->setSearchable(true); - if(this->mFactory->saveObject(CustomVideos)) return -1; -#endif - } - return 0; -} - -#ifndef WITHOUT_TV -int cMediaDatabase::loadChannels(){ - MESSAGE(VERBOSE_LIVE_TV ,"Loading channels"); - cUPnPClassContainer* TV = (cUPnPClassContainer*)this->getObjectByID(3); - if(TV){ - bool noResource = false; - // TODO: Add to setup - // if an error occured while loading resources, add the channel anyway - bool addWithoutResources = false; - cChannel* Channel = NULL; - for(int Index = 0; (Channel = Channels.Get(Index)); Index = Channels.GetNextNormal(Index)){ - // Iterating the channels -// for(Channel = Channels.First(); Channel; Channel = Channels.(Channel)){ - bool inList = false; - - tChannelID ChannelID = Channel->GetChannelID(); - MESSAGE(VERBOSE_LIVE_TV, "Determine if the channel %s is already listed", *ChannelID.ToString()); - cUPnPClassVideoBroadcast* ChannelItem = NULL; - - ChannelItem = (cUPnPClassVideoBroadcast*)this->getObjectByFastFind(ChannelID.ToString()); - - inList = (ChannelItem && TV->getObject(ChannelItem->getID())) ? true : false; - - if(!inList){ - if(Channel->GroupSep()){ - MESSAGE(VERBOSE_LIVE_TV, "Skipping group '%s'", Channel->Name()); - // Skip channel groups - // Channel groups may be supported theoretically. However, DLNA states that a tuner needs - // a consecutive list of channels. A simple work-around may be a virtual tuner for each group. - } - else if(Channel->Vpid()==0){ - // TODO: add radio support - MESSAGE(VERBOSE_LIVE_TV, "Skipping radio '%s'", Channel->Name()); - } - else { - noResource = false; - MESSAGE(VERBOSE_LIVE_TV, "Adding channel '%s' ID:%s", Channel->Name(), *ChannelID.ToString()); - ChannelItem = (cUPnPClassVideoBroadcast*)this->mFactory->createObject(UPNP_CLASS_VIDEOBC, Channel->Name()); - ChannelItem->setChannelName(Channel->Name()); - ChannelItem->setChannelNr(Channel->Number()); - // Set primary language of the stream - if(Channel->Alang(0)){ - ChannelItem->setLanguage(Channel->Alang(0)); - } - if(cUPnPResources::getInstance()->createFromChannel(ChannelItem, Channel)){ - ERROR("Unable to get resources for this channel"); - noResource = true; - } - if(!noResource || addWithoutResources) { - TV->addObject(ChannelItem); - if(this->mFactory->saveObject(ChannelItem) || - this->addFastFind(ChannelItem, ChannelID.ToString())){ - this->mFactory->deleteObject(ChannelItem); - return -1; - } - MESSAGE(VERBOSE_LIVE_TV, "Successfuly added channel"); - } - else { - // Delete temporarily created object with no resource - this->mFactory->deleteObject(ChannelItem); - } - } - } - else { - MESSAGE(VERBOSE_LIVE_TV, "Skipping %s, already in database", Channel->Name()); - } - } - } - return 0; -} - -void cMediaDatabase::updateChannelEPG(){ - cUPnPClassContainer* TV = (cUPnPClassContainer*)this->getObjectByID(3); - if(TV){ - // Iterating channels - MESSAGE(VERBOSE_EPG_UPDATES, "Getting schedule..."); - cSchedulesLock SchedulesLock; - const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); - - cList<cUPnPClassObject>* List = TV->getObjectList(); - MESSAGE(VERBOSE_EPG_UPDATES, "TV folder has %d items", List->Count()); - for(cUPnPClassVideoBroadcast* ChannelItem = (cUPnPClassVideoBroadcast*)List->First(); - ChannelItem; - ChannelItem = (cUPnPClassVideoBroadcast*)List->Next(ChannelItem) - ){ - MESSAGE(VERBOSE_EPG_UPDATES, "Find channel by number %d", ChannelItem->getChannelNr()); - cChannel* Channel = Channels.GetByNumber(ChannelItem->getChannelNr()); - - if(!Channel){ - continue; - } - else { - MESSAGE(VERBOSE_EPG_UPDATES, "Found channel with ID %s", *Channel->GetChannelID().ToString()); - - const cSchedule* Schedule = Schedules->GetSchedule(Channel); - const cEvent* Event = Schedule?Schedule->GetPresentEvent():NULL; - if(Event){ - - time_t LastEPGChange = Event->StartTime(); - time_t LastObjectChange = ChannelItem->modified(); - - MESSAGE(VERBOSE_EPG_UPDATES, "Last event start: %s", ctime(&LastEPGChange)); - MESSAGE(VERBOSE_EPG_UPDATES, "Last object modification: %s", ctime(&LastObjectChange)); - if(LastEPGChange >= LastObjectChange){ - MESSAGE(VERBOSE_EPG_UPDATES, "Updating details"); - - if(Event){ - ChannelItem->setTitle(Event->Title()?Event->Title():Channel->Name()); - ChannelItem->setLongDescription(Event->Description()); - ChannelItem->setDescription(Event->ShortText()); - } - else { - ChannelItem->setTitle(Channel->Name()); - ChannelItem->setLongDescription(NULL); - ChannelItem->setDescription(NULL); - } - - this->mFactory->saveObject(ChannelItem); - } - else { - MESSAGE(VERBOSE_EPG_UPDATES, "Channel did not change"); - } - } - else { - MESSAGE(VERBOSE_EPG_UPDATES, "No EPG data"); - ChannelItem->setTitle(Channel->Name()); - ChannelItem->setLongDescription(NULL); - ChannelItem->setDescription(NULL); - } - } - } - } -} -#endif -#ifndef WITHOUT_RECORDS -int cMediaDatabase::loadRecordings(){ - MESSAGE(VERBOSE_RECORDS, "Loading recordings"); - cUPnPClassContainer* Records = (cUPnPClassContainer*)this->getObjectByID(4); - if(Records){ - bool noResource = false; - // TODO: Add to setup - // if an error occured while loading resources, add the channel anyway - bool addWithoutResources = false; - cRecording* Recording = NULL; - for(Recording = Recordings.First(); Recording; Recording = Recordings.Next(Recording)){ - // Iterating the records - bool inList = false; - - MESSAGE(VERBOSE_RECORDS, "Determine if the channel %s is already listed", Recording->FileName()); - - cUPnPClassMovie *MovieItem = NULL; - - MovieItem = (cUPnPClassMovie*)this->getObjectByFastFind(Recording->FileName()); - - inList = (MovieItem && Records->getObject(MovieItem->getID())) ? true : false; - - if(!inList){ - noResource = false; - const cRecordingInfo* RecInfo = Recording->Info(); - - MESSAGE(VERBOSE_RECORDS, "Adding movie '%s' File name:%s", RecInfo->Title(), Recording->FileName()); - - MovieItem = (cUPnPClassMovie*)this->mFactory->createObject(UPNP_CLASS_MOVIE, RecInfo->Title()?RecInfo->Title():Recording->Name()); - MovieItem->setDescription(RecInfo->ShortText()); - MovieItem->setLongDescription(RecInfo->Description()); - MovieItem->setStorageMedium(UPNP_STORAGE_HDD); - - if(RecInfo->Components()){ - // The first component - tComponent *Component = RecInfo->Components()->Component(0); - if(Component) MovieItem->setLanguage(Component->language); - } - - if(cUPnPResources::getInstance()->createFromRecording(MovieItem, Recording)){ - ERROR("Unable to get resources for this channel"); - noResource = true; - } - if(!noResource || addWithoutResources) { - Records->addObject(MovieItem); - if(this->mFactory->saveObject(MovieItem) || - this->addFastFind(MovieItem, Recording->FileName())){ - this->mFactory->deleteObject(MovieItem); - return -1; - } - MESSAGE(VERBOSE_RECORDS, "Successfuly added movie"); - } - else { - // Delete temporarily created object with no resource - this->mFactory->deleteObject(MovieItem); - } - } - else { - MESSAGE(VERBOSE_RECORDS, "Skipping %s, already in Database", Recording->FileName()); - } - } - } - return 0; -} -#endif - -void cMediaDatabase::Action(){ - time_t LastEPGUpdate = 0; - while(this->Running()){ - -#ifndef WITHOUT_TV - if(cSchedules::Modified() >= LastEPGUpdate){ - MESSAGE(VERBOSE_EPG_UPDATES, "Schedule changed. Updating..."); - updateChannelEPG(); - LastEPGUpdate = cSchedules::Modified(); - } -#endif -#ifndef WITHOUT_RECORDS - int NotUsed; - if(Recordings.StateChanged(NotUsed)){ - MESSAGE(VERBOSE_EPG_UPDATES, "Recordings changed. Updating..."); - loadRecordings(); - } -#endif - - cCondWait::SleepMs(60 * 1000); // sleep a minute - } -} - -int cMediaDatabase::browse( - OUT cUPnPResultSet** Results, - IN const char* ID, - IN bool BrowseMetadata, - IN const char* Filter, - IN unsigned int Offset, - IN unsigned int Count, - IN const char* SortCriteria -){ - *Results = new cUPnPResultSet; - (*Results)->mNumberReturned = 0; - (*Results)->mTotalMatches = 0; - (*Results)->mResult = NULL; - - MESSAGE(VERBOSE_DIDL, "===== Browsing ====="); - MESSAGE(VERBOSE_DIDL, "ID: %s", ID); - MESSAGE(VERBOSE_DIDL, "Browse %s", BrowseMetadata?"metadata":"children"); - MESSAGE(VERBOSE_DIDL, "Filter: %s", Filter); - MESSAGE(VERBOSE_DIDL, "Offset: %d", Offset); - MESSAGE(VERBOSE_DIDL, "Count: %d", Count); - MESSAGE(VERBOSE_DIDL, "Sort: %s", SortCriteria); - - cUPnPObjectID ObjectID = atoi(ID); - - cStringList* FilterList = cFilterCriteria::parse(Filter); - cList<cSortCrit>* SortCriterias = cSortCriteria::parse(SortCriteria); - - if(!SortCriterias){ - return UPNP_CDS_E_INVALID_SORT_CRITERIA; - } - - cUPnPClassObject* Object = this->getObjectByID(ObjectID); - if(Object){ - IXML_Document* DIDLDoc = NULL; - if(ixmlParseBufferEx(UPNP_DIDL_SKELETON, &DIDLDoc)==IXML_SUCCESS){ - - IXML_Node* Root = ixmlNode_getFirstChild((IXML_Node*) DIDLDoc); - switch(BrowseMetadata){ - case true: - ixmlNode_appendChild(Root, Object->createDIDLFragment(DIDLDoc, FilterList)); - delete FilterList; - (*Results)->mNumberReturned = 1; - (*Results)->mTotalMatches = 1; - (*Results)->mResult = ixmlDocumenttoString(DIDLDoc); - ixmlDocument_free(DIDLDoc); - return UPNP_E_SUCCESS; - case false: - if(Object->isContainer()){ - cUPnPClassContainer* Container = Object->getContainer(); - (*Results)->mTotalMatches = Container->getChildCount(); - cUPnPObjects* Children = Container->getObjectList(); - - if(SortCriterias){ - for(cSortCrit* SortBy = SortCriterias->First(); SortBy ; SortBy = SortCriterias->Next(SortBy)){ - MESSAGE(VERBOSE_DIDL, "Sorting by %s %s", SortBy->Property, SortBy->SortDescending?"ascending":"descending"); - Children->SortBy(SortBy->Property, SortBy->SortDescending); - } - } - - cUPnPClassObject* Child = Children->First(); - if(Count==0 || Count > Container->getChildCount()) - Count = Container->getChildCount(); - - MESSAGE(VERBOSE_DIDL, "Number of children: %d", Count); - while(Offset-- && (Child = Children->Next(Child))){} - for(; Count && Child ; Child = Children->Next(Child), Count--){ - MESSAGE(VERBOSE_DIDL, "Appending %s to didl", Child->getTitle()); - ixmlNode_appendChild(Root, Child->createDIDLFragment(DIDLDoc, FilterList)); - (*Results)->mNumberReturned++; - } - delete FilterList; - delete SortCriterias; - } - else { - (*Results)->mNumberReturned = 0; - (*Results)->mTotalMatches = 0; - } - (*Results)->mResult = ixmlDocumenttoString(DIDLDoc); - ixmlDocument_free(DIDLDoc); - return UPNP_E_SUCCESS; - } - } - else { - ERROR("Unable to parse DIDL skeleton"); - return UPNP_CDS_E_CANT_PROCESS_REQUEST; - } - } - else { - ERROR("No such object: %s", ID); - return UPNP_CDS_E_NO_SUCH_OBJECT; // No such object; - } - return UPNP_SOAP_E_ACTION_FAILED; -}
\ No newline at end of file diff --git a/database/object.cpp b/database/object.cpp deleted file mode 100644 index b193567..0000000 --- a/database/object.cpp +++ /dev/null @@ -1,1887 +0,0 @@ -/* - * File: object.cpp - * Author: savop - * - * Created on 11. September 2009, 20:39 - */ - -#include <string.h> -#include <stdio.h> -#include <upnp/upnptools.h> -#include <vdr/recording.h> -#include <vector> -#include "database.h" -#include <vdr/tools.h> -#include <upnp/ixml.h> -#include "metadata.h" -#include "object.h" -#include "../common.h" -#include "resources.h" - -static int CompareUPnPObjects(const void *a, const void *b){ - const cUPnPClassObject *la = *(const cUPnPClassObject **)a; - const cUPnPClassObject *lb = *(const cUPnPClassObject **)b; - return la->Compare(*lb); -} - -cUPnPObjects::cUPnPObjects(){} - -cUPnPObjects::~cUPnPObjects(){} - -void cUPnPObjects::SortBy(const char* Property, bool Descending){ - int n = Count(); - cUPnPClassObject *a[n]; - cUPnPClassObject *object = (cUPnPClassObject *)objects; - int i = 0; - while (object && i < n) { - object->setSortCriteria(Property, Descending); - a[i++] = object; - object = (cUPnPClassObject *)object->Next(); - } - qsort(a, n, sizeof(cUPnPClassObject *), CompareUPnPObjects); - objects = lastObject = NULL; - for (i = 0; i < n; i++) { - a[i]->Unlink(); - count--; - Add(a[i]); - } -} - - /**********************************************\ - * * - * UPnP Objects * - * * - \**********************************************/ - - /**********************************************\ - * * - * Object * - * * - \**********************************************/ - -cUPnPClassObject::cUPnPClassObject(){ - this->mID = -1; - this->mLastID = -1; - this->mResources = new cList<cUPnPResource>; - this->mResourcesID = new cHash<cUPnPResource>; - this->mParent = NULL; - this->mClass = NULL; - this->mCreator = NULL; - this->mTitle = NULL; - this->mWriteStatus = WS_UNKNOWN; - this->mRestricted = true; - this->mDIDLFragment = NULL; - this->mSortCriteria = NULL; - this->mLastModified = NULL; -} - -cUPnPClassObject::~cUPnPClassObject(){ - if(this->mParent) this->mParent->getContainer()->removeObject(this); - this->mResources->Clear(); - this->mResourcesID->Clear(); - delete this->mResources; - delete this->mResourcesID; - free(this->mDIDLFragment); -} - -int cUPnPClassObject::Compare(const cListObject& ListObject) const { - char* Value1 = NULL; char* Value2 = NULL; int ret = 0; - cUPnPClassObject* Object = (cUPnPClassObject*)&ListObject; - if(Object->getProperty(this->mSortCriteria, &Value1) && - this->getProperty(this->mSortCriteria, &Value2)){ - ret = strcmp(Value1, Value2); - if(this->mSortDescending) ret *= -1; - } - return ret; -} - -void cUPnPClassObject::setSortCriteria(const char* Property, bool Descending){ - this->mSortCriteria = Property; - this->mSortDescending = Descending; -} - -void cUPnPClassObject::clearSortCriteria(){ - this->mSortCriteria = NULL; - this->mSortDescending = false; -} - -int cUPnPClassObject::setID(cUPnPObjectID ID){ - MESSAGE(VERBOSE_MODIFICATIONS, "Set ID from %s to %s", *this->getID(),*ID); - if((int)ID < 0){ - ERROR("Invalid object ID '%s'",*ID); - return -1; - } - this->mLastID = (this->mID==-1) ? ID : this->mID; - this->mID = ID; - return 0; -} - -int cUPnPClassObject::setParent(cUPnPClassContainer* Parent){ - if(Parent==NULL){ - MESSAGE(VERBOSE_MODIFICATIONS, "Object '%s' elected as root object", *this->getID()); - } - // unregister from old parent - if(this->mParent && Parent != this->mParent){ - this->mParent->getContainer()->removeObject(this); - } - this->mParent = Parent; - return 0; -} - -int cUPnPClassObject::setClass(const char* Class){ - if( !strcasecmp(Class, UPNP_CLASS_ALBUM) || - !strcasecmp(Class, UPNP_CLASS_AUDIO) || - !strcasecmp(Class, UPNP_CLASS_AUDIOBC) || - !strcasecmp(Class, UPNP_CLASS_AUDIOBOOK) || - !strcasecmp(Class, UPNP_CLASS_CONTAINER) || - !strcasecmp(Class, UPNP_CLASS_GENRE) || - !strcasecmp(Class, UPNP_CLASS_IMAGE) || - !strcasecmp(Class, UPNP_CLASS_ITEM) || - !strcasecmp(Class, UPNP_CLASS_MOVIE) || - !strcasecmp(Class, UPNP_CLASS_MOVIEGENRE) || - !strcasecmp(Class, UPNP_CLASS_MUSICALBUM) || - !strcasecmp(Class, UPNP_CLASS_MUSICARTIST) || - !strcasecmp(Class, UPNP_CLASS_MUSICGENRE) || - !strcasecmp(Class, UPNP_CLASS_MUSICTRACK) || - !strcasecmp(Class, UPNP_CLASS_MUSICVIDCLIP) || - !strcasecmp(Class, UPNP_CLASS_OBJECT) || - !strcasecmp(Class, UPNP_CLASS_PERSON) || - !strcasecmp(Class, UPNP_CLASS_PHOTO) || - !strcasecmp(Class, UPNP_CLASS_PHOTOALBUM) || - !strcasecmp(Class, UPNP_CLASS_PLAYLIST) || - !strcasecmp(Class, UPNP_CLASS_PLAYLISTCONT) || - !strcasecmp(Class, UPNP_CLASS_STORAGEFOLD) || - !strcasecmp(Class, UPNP_CLASS_STORAGESYS) || - !strcasecmp(Class, UPNP_CLASS_STORAGEVOL) || - !strcasecmp(Class, UPNP_CLASS_TEXT) || - !strcasecmp(Class, UPNP_CLASS_VIDEO) || - !strcasecmp(Class, UPNP_CLASS_VIDEOBC) - ){ - this->mClass = strdup0(Class); - return 0; - } - else { - ERROR("Invalid or unsupported class '%s'", Class); - return -1; - } -} - -int cUPnPClassObject::setTitle(const char* Title){ - if(Title==NULL){ - ERROR("Title is empty but required"); - return -1; - } - this->mTitle = strdup0(Title); - return 0; -} - -int cUPnPClassObject::setCreator(const char* Creator){ - this->mCreator = strdup0(Creator); - return 0; -} - -int cUPnPClassObject::setRestricted(bool Restricted){ - this->mRestricted = Restricted; - return 0; -} - -int cUPnPClassObject::setWriteStatus(int WriteStatus){ - if( WriteStatus == WS_MIXED || - WriteStatus == WS_NOT_WRITABLE || - WriteStatus == WS_PROTECTED || - WriteStatus == WS_UNKNOWN || - WriteStatus == WS_WRITABLE){ - this->mWriteStatus = WriteStatus; - return 0; - } - else { - ERROR("Invalid write status '%d'", WriteStatus); - return -1; - } -} - -bool cUPnPClassObject::getProperty(const char* Property, char** Value) const { - cString Val; - if(!strcasecmp(Property, SQLITE_COL_OBJECTID) || !strcasecmp(Property, UPNP_PROP_OBJECTID)){ - Val = *this->getID(); - } - else if(!strcasecmp(Property, SQLITE_COL_PARENTID) || !strcasecmp(Property, UPNP_PROP_PARENTID)){ - Val = *this->getParentID(); - } - else if(!strcasecmp(Property, SQLITE_COL_CLASS) || !strcasecmp(Property, UPNP_PROP_CLASS)){ - Val = this->getClass(); - } - else if(!strcasecmp(Property, SQLITE_COL_TITLE) || !strcasecmp(Property, UPNP_PROP_TITLE)){ - Val = this->getTitle(); - } - else if(!strcasecmp(Property, SQLITE_COL_CREATOR) || !strcasecmp(Property, UPNP_PROP_CREATOR)){ - Val = this->getCreator(); - } - else if(!strcasecmp(Property, SQLITE_COL_RESTRICTED) || !strcasecmp(Property, UPNP_PROP_RESTRICTED)){ - Val = this->isRestricted()?"1":"0"; - } - else if(!strcasecmp(Property, SQLITE_COL_WRITESTATUS) || !strcasecmp(Property, UPNP_PROP_WRITESTATUS)){ - Val = itoa(this->getWriteStatus()); - } - else { - ERROR("Invalid property '%s'", Property); - return false; - } - *Value = strdup0(*Val); - return true; -} - -cStringList* cUPnPClassObject::getPropertyList(){ - cStringList* Properties = new cStringList; - Properties->Append(strdup(UPNP_PROP_CREATOR)); - Properties->Append(strdup(UPNP_PROP_WRITESTATUS)); - return Properties; -} - -bool cUPnPClassObject::setProperty(const char* Property, const char* Value){ - int ret; - if(!strcasecmp(Property, SQLITE_COL_OBJECTID) || !strcasecmp(Property, UPNP_PROP_OBJECTID)){ - ERROR("Not allowed to set object ID by hand"); - return false; - } - else if(!strcasecmp(Property, SQLITE_COL_PARENTID) || !strcasecmp(Property, UPNP_PROP_PARENTID)){ - ERROR("Not allowed to set parent ID by hand"); - return false; - } - else if(!strcasecmp(Property, SQLITE_COL_CLASS) || !strcasecmp(Property, UPNP_PROP_CLASS)){ - ERROR("Not allowed to set class by hand"); - return false; - } - else if(!strcasecmp(Property, SQLITE_COL_TITLE) || !strcasecmp(Property, UPNP_PROP_TITLE)){ - ret = this->setTitle(Value); - } - else if(!strcasecmp(Property, SQLITE_COL_CREATOR) || !strcasecmp(Property, UPNP_PROP_CREATOR)){ - ret = this->setCreator(Value); - } - else if(!strcasecmp(Property, SQLITE_COL_RESTRICTED) || !strcasecmp(Property, UPNP_PROP_RESTRICTED)){ - ret = this->setRestricted(atoi(Value)==1?true:false); - } - else if(!strcasecmp(Property, SQLITE_COL_WRITESTATUS) || !strcasecmp(Property, UPNP_PROP_WRITESTATUS)){ - ret= this->setWriteStatus(atoi(Value)); - } - else { - ERROR("Invalid property '%s'", Property); - return false; - } - return ret<0?false:true; -} - -int cUPnPClassObject::addResource(cUPnPResource* Resource){ - MESSAGE(VERBOSE_MODIFICATIONS, "Adding resource #%d", Resource->getID()); - if(!Resource){ - ERROR("No resource"); - return -1; - } - this->mResources->Add(Resource); - this->mResourcesID->Add(Resource, Resource->getID()); - return 0; -} - -int cUPnPClassObject::removeResource(cUPnPResource* Resource){ - if(!Resource){ - ERROR("No resource"); - return -1; - } - this->mResourcesID->Del(Resource, Resource->getID()); - this->mResources->Del(Resource); - return 0; -} - - /**********************************************\ - * * - * Item * - * * - \**********************************************/ - -cUPnPClassItem::cUPnPClassItem(){ - this->setClass(UPNP_CLASS_ITEM); - this->mReference = NULL; -} - -int cUPnPClassItem::setReference(cUPnPClassItem* Reference){ - this->mReference = Reference; - return 0; -} - -cStringList* cUPnPClassItem::getPropertyList(){ - cStringList* Properties = cUPnPClassObject::getPropertyList(); - Properties->Append(strdup(UPNP_PROP_REFERENCEID)); - return Properties; -} - -bool cUPnPClassItem::getProperty(const char* Property, char** Value) const { - - if(!strcasecmp(Property, SQLITE_COL_REFERENCEID) || !strcasecmp(Property, UPNP_PROP_REFERENCEID)){ - *Value = strdup0(*this->getReferenceID()); - } - else return cUPnPClassObject::getProperty(Property, Value); - return true; -} - -bool cUPnPClassItem::setProperty(const char* Property, const char* Value){ - return cUPnPClassObject::setProperty(Property, Value); -} - -IXML_Node* cUPnPClassItem::createDIDLFragment(IXML_Document* Document, cStringList* Filter){ - this->mDIDLFragment = Document; - - MESSAGE(VERBOSE_DIDL, "==(%s)= %s =====", *this->getID(), this->getTitle()); - MESSAGE(VERBOSE_DIDL, "ParentID: %s", *this->getParentID()); - MESSAGE(VERBOSE_DIDL, "Restricted: %s", this->isRestricted()?"1":"0"); - MESSAGE(VERBOSE_DIDL, "Class: %s", this->getClass()); - MESSAGE(VERBOSE_DIDL, "Filter: %d", Filter?Filter->Size():-1); - - IXML_Node* Didl = ixmlNode_getFirstChild((IXML_Node*) this->mDIDLFragment); - - IXML_Element* eItem = ixmlDocument_createElement(this->mDIDLFragment, "item"); - ixmlNode_appendChild(Didl, (IXML_Node*) eItem); - - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_OBJECTID, *this->getID()); - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_PARENTID, *this->getParentID()); - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_RESTRICTED, this->isRestricted()?"1":"0"); - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_TITLE, this->getTitle()); - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_CLASS, this->getClass()); - - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CREATOR, this->getCreator()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_WRITESTATUS, itoa(this->getWriteStatus())); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_REFERENCEID, ((int)(this->getReferenceID())<0)?"":*this->getReferenceID()); - - for(cUPnPResource* Resource = this->getResources()->First(); Resource; Resource = this->getResources()->Next(Resource)){ - MESSAGE(VERBOSE_DIDL, "Resource: %s", Resource->getResource()); - MESSAGE(VERBOSE_DIDL, "Protocolinfo: %s", Resource->getProtocolInfo()); - - cString URLBase = cString::sprintf("http://%s:%d", UpnpGetServerIpAddress(), UpnpGetServerPort()); - cString ResourceURL = cString::sprintf("%s%s/get?resId=%d", *URLBase, UPNP_DIR_SHARES, Resource->getID()); - - MESSAGE(VERBOSE_DIDL, "Resource-URI: %s", *ResourceURL); - - IXML_Element* eRes = ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_RESOURCE, *ResourceURL); - if(eRes){ - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_BITRATE, itoa(Resource->getBitrate())); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_BITSPERSAMPLE, itoa(Resource->getBitsPerSample())); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_COLORDEPTH, itoa(Resource->getColorDepth())); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_DURATION, Resource->getDuration()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_PROTOCOLINFO, Resource->getProtocolInfo()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_SIZE, cString::sprintf("%lld", Resource->getFileSize())); - } - - } - - return (IXML_Node*)eItem; -} - - /**********************************************\ - * * - * Container * - * * - \**********************************************/ - -cUPnPClassContainer::cUPnPClassContainer(){ - this->setClass(UPNP_CLASS_CONTAINER); - this->mChildren = new cUPnPObjects; - this->mChildrenID = new cHash<cUPnPClassObject>; - this->mContainerType = NULL; - this->mUpdateID = 0; - this->mSearchable = false; -} - -cUPnPClassContainer::~cUPnPClassContainer(){ - delete this->mChildren; - delete this->mChildrenID; -} - -IXML_Node* cUPnPClassContainer::createDIDLFragment(IXML_Document* Document, cStringList* Filter){ - this->mDIDLFragment = Document; - - MESSAGE(VERBOSE_DIDL, "===(%s)= %s =====", *this->getID(), this->getTitle()); - MESSAGE(VERBOSE_DIDL, "ParentID: %s", *this->getParentID()); - MESSAGE(VERBOSE_DIDL, "Restricted: %s", this->isRestricted()?"1":"0"); - MESSAGE(VERBOSE_DIDL, "Class: %s", this->getClass()); - MESSAGE(VERBOSE_DIDL, "Filter: %d", Filter?Filter->Size():-1); - - IXML_Node* Didl = ixmlNode_getFirstChild((IXML_Node*) this->mDIDLFragment); - IXML_Element* eItem = ixmlDocument_createElement(this->mDIDLFragment, "container"); - ixmlNode_appendChild(Didl, (IXML_Node*) eItem); - - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_OBJECTID, *this->getID()); - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_PARENTID, *this->getParentID()); - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_RESTRICTED, this->isRestricted()?"1":"0"); - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_TITLE, this->getTitle()); - ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_CLASS, this->getClass()); - - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_DLNA_CONTAINERTYPE, this->getContainerType()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CHILDCOUNT, itoa(this->getChildCount())); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_SEARCHABLE, this->isSearchable()?"1":"0"); - - const tClassVector* CreateClasses = this->getCreateClasses(); - for(unsigned int i = 0; i < CreateClasses->size(); i++){ - cClass CreateClass = CreateClasses->at(i); - IXML_Element* eCreateClasses = ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CREATECLASS, CreateClass.ID); - if(eCreateClasses) - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CCLASSDERIVED, CreateClass.includeDerived?"1":"0"); - } - - const tClassVector* SearchClasses = this->getSearchClasses(); - for(unsigned int i = 0; i < SearchClasses->size(); i++){ - cClass SearchClass = SearchClasses->at(i); - IXML_Element* eSearchClasses = ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_SEARCHCLASS, SearchClass.ID); - if(eSearchClasses) - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_SCLASSDERIVED, SearchClass.includeDerived?"1":"0"); - } - - return (IXML_Node*)eItem; -} - -int cUPnPClassContainer::setUpdateID(unsigned int UID){ - this->mUpdateID = UID; - return 0; -} - -cStringList* cUPnPClassContainer::getPropertyList(){ - cStringList* Properties = cUPnPClassObject::getPropertyList(); - Properties->Append(strdup(UPNP_PROP_DLNA_CONTAINERTYPE)); - Properties->Append(strdup(UPNP_PROP_SEARCHABLE)); - return Properties; -} - -bool cUPnPClassContainer::setProperty(const char* Property, const char* Value){ - int ret; - if(!strcasecmp(Property, SQLITE_COL_DLNA_CONTAINERTYPE) || !strcasecmp(Property, UPNP_PROP_DLNA_CONTAINERTYPE)){ - ret = this->setContainerType(Value); - } - else if(!strcasecmp(Property, SQLITE_COL_SEARCHABLE) || !strcasecmp(Property, UPNP_PROP_SEARCHABLE)){ - ret = this->setSearchable(Value); - } - else if(!strcasecmp(Property, SQLITE_COL_CONTAINER_UID)){ - ret = this->setUpdateID((unsigned int)atoi(Value)); - } - else return cUPnPClassObject::setProperty(Property, Value); - return ret<0?false:true; -} - -bool cUPnPClassContainer::getProperty(const char* Property, char** Value) const { - cString Val; - if(!strcasecmp(Property, SQLITE_COL_DLNA_CONTAINERTYPE) || !strcasecmp(Property, UPNP_PROP_DLNA_CONTAINERTYPE)){ - Val = this->getContainerType(); - } - else if(!strcasecmp(Property, SQLITE_COL_SEARCHABLE) || !strcasecmp(Property, UPNP_PROP_SEARCHABLE)){ - Val = this->isSearchable()?"1":"0"; - } - else if(!strcasecmp(Property, SQLITE_COL_CONTAINER_UID)){ - Val = cString::sprintf("%d", this->getUpdateID()); - } - else return cUPnPClassObject::getProperty(Property, Value); - *Value = strdup0(*Val); - return true; -} - -void cUPnPClassContainer::addObject(cUPnPClassObject* Object){ - MESSAGE(VERBOSE_MODIFICATIONS, "Adding object (ID:%s) to container (ID:%s)", *Object->getID(), *this->getID()); - Object->setParent(this); - this->mChildren->Add(Object); - this->mChildrenID->Add(Object, (unsigned int)Object->getID()); -} - -void cUPnPClassContainer::removeObject(cUPnPClassObject* Object){ - this->mChildrenID->Del(Object, (unsigned int)Object->getID()); - this->mChildren->Del(Object, false); - Object->mParent = NULL; - MESSAGE(VERBOSE_MODIFICATIONS, "Removed object (ID:%s) from container (ID:%s)", *Object->getID(), *this->getID()); -} - -cUPnPClassObject* cUPnPClassContainer::getObject(cUPnPObjectID ID) const { - MESSAGE(VERBOSE_METADATA, "Getting object (ID:%s)", *ID); - if((int)ID < 0){ - ERROR("Invalid object ID"); - return NULL; - } - return this->mChildrenID->Get((unsigned int)ID); -} - -int cUPnPClassContainer::setContainerType(const char* Type){ - if(Type==NULL){ - this->mContainerType = Type; - } - else if(!strcasecmp(Type, DLNA_CONTAINER_TUNER)){ - this->mContainerType = Type; - } - else { - ERROR("Invalid container type '%s'",Type); - return -1; - } - return 0; -} - -int cUPnPClassContainer::addSearchClass(cClass SearchClass){ - this->mSearchClasses.push_back(SearchClass); - return 0; -} - -int cUPnPClassContainer::delSearchClass(cClass SearchClass){ - tClassVector::iterator it = this->mSearchClasses.begin(); - cClass Class; - for(unsigned int i=0; i<this->mSearchClasses.size(); i++){ - Class = this->mSearchClasses[i]; - if(Class == SearchClass){ - this->mSearchClasses.erase(it+i); - return 0; - } - } - return -1; -} - -int cUPnPClassContainer::addCreateClass(cClass CreateClass){ - this->mCreateClasses.push_back(CreateClass); - return 0; -} - -int cUPnPClassContainer::delCreateClass(cClass CreateClass){ - tClassVector::iterator it = this->mCreateClasses.begin(); - cClass Class; - for(unsigned int i=0; i<this->mCreateClasses.size(); i++){ - Class = this->mCreateClasses[i]; - if(Class == CreateClass){ - this->mCreateClasses.erase(it+i); - return 0; - } - } - return -1; -} - -int cUPnPClassContainer::setSearchClasses(std::vector<cClass> SearchClasses){ - this->mSearchClasses = SearchClasses; - return 0; -} - -int cUPnPClassContainer::setCreateClasses(std::vector<cClass> CreateClasses){ - this->mCreateClasses = CreateClasses; - return 0; -} - -int cUPnPClassContainer::setSearchable(bool Searchable){ - this->mSearchable = Searchable; - return 0; -} - -bool cUPnPClassContainer::isUpdated(){ - static unsigned int lastUpdateID = this->getUpdateID(); - if(lastUpdateID != this->getUpdateID()){ - lastUpdateID = this->getUpdateID(); - return true; - } - else return false; -} - - /**********************************************\ - * * - * Video item * - * * - \**********************************************/ - -cUPnPClassVideoItem::cUPnPClassVideoItem(){ - this->setClass(UPNP_CLASS_VIDEO); - this->mGenre = NULL; - this->mLongDescription = NULL; - this->mProducers = NULL; - this->mRating = NULL; - this->mActors = NULL; - this->mDirectors = NULL; - this->mDescription = NULL; - this->mPublishers = NULL; - this->mLanguage = NULL; - this->mRelations = NULL; -} - -cUPnPClassVideoItem::~cUPnPClassVideoItem(){ -} - -IXML_Node* cUPnPClassVideoItem::createDIDLFragment(IXML_Document* Document, cStringList* Filter){ - IXML_Element* eItem = (IXML_Element*) cUPnPClassItem::createDIDLFragment(Document, Filter); - - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_LONGDESCRIPTION, this->getLongDescription()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_DESCRIPTION, this->getDescription()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_LANGUAGE, this->getLanguage()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_RATING, this->getRating()); - - char* genre = strtok(strdup0(this->getGenre()), ","); - while(genre){ - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_GENRE, genre); - genre = strtok(NULL, ","); - } - - char* producer = strtok(strdup0(this->getProducers()), ","); - while(producer){ - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_PRODUCER, producer); - producer = strtok(NULL, ","); - } - - char* actor = strtok(strdup0(this->getActors()), ","); - while(actor){ - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_ACTOR, actor); - actor = strtok(NULL, ","); - } - - char* director = strtok(strdup0(this->getDirectors()), ","); - while(director){ - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_DIRECTOR, director); - director = strtok(NULL, ","); - } - - char* publisher = strtok(strdup0(this->getPublishers()), ","); - while(publisher){ - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_PUBLISHER, publisher); - publisher = strtok(NULL, ","); - } - - char* relation = strtok(strdup0(this->getRelations()), ","); - while(relation){ - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_RELATION, relation); - relation = strtok(NULL, ","); - } - - return (IXML_Node*) eItem; -} - -cStringList* cUPnPClassVideoItem::getPropertyList(){ - cStringList* Properties = cUPnPClassItem::getPropertyList(); - Properties->Append(strdup(UPNP_PROP_LONGDESCRIPTION)); - Properties->Append(strdup(UPNP_PROP_PRODUCER)); - Properties->Append(strdup(UPNP_PROP_GENRE)); - Properties->Append(strdup(UPNP_PROP_RATING)); - Properties->Append(strdup(UPNP_PROP_ACTOR)); - Properties->Append(strdup(UPNP_PROP_DIRECTOR)); - Properties->Append(strdup(UPNP_PROP_DESCRIPTION)); - Properties->Append(strdup(UPNP_PROP_PUBLISHER)); - Properties->Append(strdup(UPNP_PROP_LANGUAGE)); - Properties->Append(strdup(UPNP_PROP_RELATION)); - return Properties; -} - -bool cUPnPClassVideoItem::getProperty(const char* Property, char** Value) const { - cString Val; - if(!strcasecmp(Property,SQLITE_COL_GENRE) || !strcasecmp(Property,UPNP_PROP_GENRE)){ - Val = this->getGenre(); - } - else if(!strcasecmp(Property,SQLITE_COL_LONGDESCRIPTION) || !strcasecmp(Property,UPNP_PROP_LONGDESCRIPTION)){ - Val = this->getLongDescription(); - } - else if(!strcasecmp(Property,SQLITE_COL_PRODUCER) || !strcasecmp(Property,UPNP_PROP_PRODUCER)){ - Val = this->getProducers(); - } - else if(!strcasecmp(Property,SQLITE_COL_RATING) || !strcasecmp(Property,UPNP_PROP_RATING)){ - Val = this->getRating(); - } - else if(!strcasecmp(Property,SQLITE_COL_ACTOR) || !strcasecmp(Property,UPNP_PROP_ACTOR)){ - Val = this->getActors(); - } - else if(!strcasecmp(Property,SQLITE_COL_DIRECTOR) || !strcasecmp(Property,UPNP_PROP_DIRECTOR)){ - Val = this->getDirectors(); - } - else if(!strcasecmp(Property,SQLITE_COL_DESCRIPTION) || !strcasecmp(Property,UPNP_PROP_DESCRIPTION)){ - Val = this->getDescription(); - } - else if(!strcasecmp(Property,SQLITE_COL_PUBLISHER) || !strcasecmp(Property,UPNP_PROP_PUBLISHER)){ - Val = this->getPublishers(); - } - else if(!strcasecmp(Property,SQLITE_COL_LANGUAGE) || !strcasecmp(Property,UPNP_PROP_LANGUAGE)){ - Val = this->getLanguage(); - } - else if(!strcasecmp(Property,SQLITE_COL_RELATION) || !strcasecmp(Property,UPNP_PROP_RELATION)){ - Val = this->getRelations(); - } - else return cUPnPClassItem::getProperty(Property, Value); - *Value = strdup0(*Val); - return true; -} - -bool cUPnPClassVideoItem::setProperty(const char* Property, const char* Value){ - bool ret; - if(!strcasecmp(Property,SQLITE_COL_GENRE) || !strcasecmp(Property,UPNP_PROP_GENRE)){ - ret = this->setGenre(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_LONGDESCRIPTION) || !strcasecmp(Property,UPNP_PROP_LONGDESCRIPTION)){ - ret = this->setLongDescription(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_PRODUCER) || !strcasecmp(Property,UPNP_PROP_PRODUCER)){ - ret = this->setProducers(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_RATING) || !strcasecmp(Property,UPNP_PROP_RATING)){ - ret = this->setRating(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_ACTOR) || !strcasecmp(Property,UPNP_PROP_ACTOR)){ - ret = this->setActors(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_DIRECTOR) || !strcasecmp(Property,UPNP_PROP_DIRECTOR)){ - ret = this->setDirectors(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_DESCRIPTION) || !strcasecmp(Property,UPNP_PROP_DESCRIPTION)){ - ret = this->setDescription(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_PUBLISHER) || !strcasecmp(Property,UPNP_PROP_PUBLISHER)){ - ret = this->setPublishers(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_LANGUAGE) || !strcasecmp(Property,UPNP_PROP_LANGUAGE)){ - ret = this->setLanguage(Value); - } - else if(!strcasecmp(Property,SQLITE_COL_RELATION) || !strcasecmp(Property,UPNP_PROP_RELATION)){ - ret = this->setRelations(Value); - } - else return cUPnPClassItem::setProperty(Property, Value); - return ret<0?false:true; -} - -int cUPnPClassVideoItem::setActors(const char* Actors){ - this->mActors = Actors; - return 0; -} - -int cUPnPClassVideoItem::setGenre(const char* Genre){ - this->mGenre = Genre; - return 0; -} - -int cUPnPClassVideoItem::setDescription(const char* Description){ - this->mDescription = Description; - return 0; -} - -int cUPnPClassVideoItem::setLongDescription(const char* LongDescription){ - this->mLongDescription = LongDescription; - return 0; -} - -int cUPnPClassVideoItem::setProducers(const char* Producers){ - this->mProducers = Producers; - return 0; -} - -int cUPnPClassVideoItem::setRating(const char* Rating){ - this->mRating = Rating; - return 0; -} - -int cUPnPClassVideoItem::setDirectors(const char* Directors){ - this->mDirectors = Directors; - return 0; -} - -int cUPnPClassVideoItem::setPublishers(const char* Publishers){ - this->mPublishers = Publishers; - return 0; -} - -int cUPnPClassVideoItem::setLanguage(const char* Language){ - this->mLanguage = Language; - return 0; -} - -int cUPnPClassVideoItem::setRelations(const char* Relations){ - this->mRelations = Relations; - return 0; -} - - /**********************************************\ - * * - * Video Broadcast item * - * * - \**********************************************/ - -cUPnPClassVideoBroadcast::cUPnPClassVideoBroadcast(){ - this->setClass(UPNP_CLASS_VIDEOBC); - this->mIcon = NULL; - this->mRegion = NULL; - this->mChannelNr = 0; -} - -cUPnPClassVideoBroadcast::~cUPnPClassVideoBroadcast(){ -} - -IXML_Node* cUPnPClassVideoBroadcast::createDIDLFragment(IXML_Document* Document, cStringList* Filter){ - IXML_Element* eItem = (IXML_Element*) cUPnPClassItem::createDIDLFragment(Document, Filter); - - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CHANNELNAME, this->getChannelName()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CHANNELNR, itoa(this->getChannelNr())); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_ICON, this->getIcon()); - ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_REGION, this->getRegion()); - - return (IXML_Node*) eItem; -} - -cStringList* cUPnPClassVideoBroadcast::getPropertyList(){ - cStringList* Properties = cUPnPClassVideoItem::getPropertyList(); - Properties->Append(strdup(UPNP_PROP_CHANNELNAME)); - Properties->Append(strdup(UPNP_PROP_CHANNELNR)); - Properties->Append(strdup(UPNP_PROP_ICON)); - Properties->Append(strdup(UPNP_PROP_REGION)); - return Properties; -} - -bool cUPnPClassVideoBroadcast::setProperty(const char* Property, const char* Value){ - bool ret; - if(!strcasecmp(Property, SQLITE_COL_CHANNELNAME) || !strcasecmp(Property, UPNP_PROP_CHANNELNAME)){ - ret = this->setChannelName(Value); - } - else if(!strcasecmp(Property, SQLITE_COL_CHANNELNR) || !strcasecmp(Property, UPNP_PROP_CHANNELNR)){ - ret = this->setChannelNr(atoi(Value)); - } - else if(!strcasecmp(Property, SQLITE_COL_ICON) || !strcasecmp(Property, UPNP_PROP_ICON)){ - ret = this->setIcon(Value); - } - else if(!strcasecmp(Property, SQLITE_COL_REGION) || !strcasecmp(Property, UPNP_PROP_REGION)){ - ret = this->setRegion(Value); - } - else return cUPnPClassVideoItem::setProperty(Property, Value); - return ret<0?false:true; -} - -bool cUPnPClassVideoBroadcast::getProperty(const char* Property, char** Value) const { - cString Val; - if(!strcasecmp(Property, SQLITE_COL_CHANNELNAME) || !strcasecmp(Property, UPNP_PROP_CHANNELNAME)){ - Val = this->getChannelName(); - } - else if(!strcasecmp(Property, SQLITE_COL_CHANNELNR) || !strcasecmp(Property, UPNP_PROP_CHANNELNR)){ - Val = itoa(this->getChannelNr()); - } - else if(!strcasecmp(Property, SQLITE_COL_ICON) || !strcasecmp(Property, UPNP_PROP_ICON)){ - Val = this->getIcon(); - } - else if(!strcasecmp(Property, SQLITE_COL_REGION) || !strcasecmp(Property, UPNP_PROP_REGION)){ - Val = this->getRegion(); - } - else return cUPnPClassVideoItem::getProperty(Property, Value); - *Value = strdup0(*Val); - return true; -} - -int cUPnPClassVideoBroadcast::setChannelName(const char* ChannelName){ - this->mChannelName = ChannelName; - return 0; -} - -int cUPnPClassVideoBroadcast::setChannelNr(int ChannelNr){ - this->mChannelNr = ChannelNr; - return 0; -} - -int cUPnPClassVideoBroadcast::setIcon(const char* IconURI){ - this->mIcon = IconURI; - return 0; -} - -int cUPnPClassVideoBroadcast::setRegion(const char* Region){ - this->mRegion = Region; - return 0; -} - -/**********************************************\ -* * -* Movie item * -* * -\**********************************************/ - -cUPnPClassMovie::cUPnPClassMovie(){ - this->mDVDRegionCode = 2; // Europe - this->mStorageMedium = UPNP_STORAGE_UNKNOWN; -} - -cUPnPClassMovie::~cUPnPClassMovie(){} - -//cString cUPnPClassMovie::createDIDLFragment(cStringList* Filter){ -// return NULL; -//} - -cStringList* cUPnPClassMovie::getPropertyList(){ - cStringList* Properties = cUPnPClassVideoItem::getPropertyList(); - Properties->Append(strdup(UPNP_PROP_DVDREGIONCODE)); - Properties->Append(strdup(UPNP_PROP_STORAGEMEDIUM)); - return Properties; -} - -bool cUPnPClassMovie::setProperty(const char* Property, const char* Value){ - bool ret; - if(!strcasecmp(Property, SQLITE_COL_DVDREGIONCODE) || !strcasecmp(Property, UPNP_PROP_DVDREGIONCODE)){ - ret = this->setDVDRegionCode(atoi(Value)); - } - else if(!strcasecmp(Property, SQLITE_COL_STORAGEMEDIUM) || !strcasecmp(Property, UPNP_PROP_STORAGEMEDIUM)){ - ret = this->setStorageMedium(Value); - } - else return cUPnPClassVideoItem::setProperty(Property, Value); - return ret<0?false:true; -} - -bool cUPnPClassMovie::getProperty(const char* Property, char** Value) const { - cString Val; - if(!strcasecmp(Property, SQLITE_COL_DVDREGIONCODE) || !strcasecmp(Property, UPNP_PROP_DVDREGIONCODE)){ - Val = itoa(this->getDVDRegionCode()); - } - else if(!strcasecmp(Property, SQLITE_COL_STORAGEMEDIUM) || !strcasecmp(Property, UPNP_PROP_STORAGEMEDIUM)){ - Val = this->getStorageMedium(); - } - else return cUPnPClassVideoItem::getProperty(Property, Value); - *Value = strdup0(*Val); - return true; -} - -int cUPnPClassMovie::setDVDRegionCode(int RegionCode){ -// http://en.wikipedia.org/wiki/DVD_region_code -// 0 Informal term meaning "worldwide". Region 0 is not an official setting; discs that bear the region 0 symbol either have no flag set or have region 1–6 flags set. -// 1 Canada, United States; U.S. territories; Bermuda -// 2 Western Europe; incl. United Kingdom, Ireland, and Central Europe; Eastern Europe, Western Asia; including Iran, Israel, Egypt; Japan, South Africa, Swaziland, Lesotho; French overseas territories -// 3 Southeast Asia; South Korea; Taiwan; Hong Kong; Macau -// 4 Mexico, Central and South America; Caribbean; Australia; New Zealand; Oceania; -// 5 Ukraine, Belarus, Russia, Continent of Africa, excluding Egypt, South Africa, Swaziland, and Lesotho; Central and South Asia, Mongolia, North Korea. -// 6 People's Republic of China -// 7 Reserved for future use (found in use on protected screener copies of MPAA-related DVDs and "media copies" of pre-releases in Asia) -// 8 International venues such as aircraft, cruise ships, etc.[1] -// ALL (9) Region ALL discs have all 8 flags set, allowing the disc to be played in any locale on any player. - if(0 <= RegionCode && RegionCode <= 9){ - this->mDVDRegionCode = RegionCode; - return 0; - } - else { - ERROR("Invalid DVD region code: %d", RegionCode); - return -1; - } -} - -int cUPnPClassMovie::setStorageMedium(const char* StorageMedium){ - if(!StorageMedium) this->mStorageMedium = UPNP_STORAGE_UNKNOWN; - else if( - strcasecmp(StorageMedium,UPNP_STORAGE_CD_DA) && - strcasecmp(StorageMedium,UPNP_STORAGE_CD_R) && - strcasecmp(StorageMedium,UPNP_STORAGE_CD_ROM) && - strcasecmp(StorageMedium,UPNP_STORAGE_CD_RW) && - strcasecmp(StorageMedium,UPNP_STORAGE_DAT) && - strcasecmp(StorageMedium,UPNP_STORAGE_DV) && - strcasecmp(StorageMedium,UPNP_STORAGE_DVD_AUDIO) && - strcasecmp(StorageMedium,UPNP_STORAGE_DVD_RAM) && - strcasecmp(StorageMedium,UPNP_STORAGE_DVD_ROM) && - strcasecmp(StorageMedium,UPNP_STORAGE_DVD_RW_MINUS) && - strcasecmp(StorageMedium,UPNP_STORAGE_DVD_RW_PLUS) && - strcasecmp(StorageMedium,UPNP_STORAGE_DVD_R_MINUS) && - strcasecmp(StorageMedium,UPNP_STORAGE_DVD_VIDEO) && - strcasecmp(StorageMedium,UPNP_STORAGE_D_VHS) && - strcasecmp(StorageMedium,UPNP_STORAGE_HDD) && - strcasecmp(StorageMedium,UPNP_STORAGE_HI8) && - strcasecmp(StorageMedium,UPNP_STORAGE_LD) && - strcasecmp(StorageMedium,UPNP_STORAGE_MD_AUDIO) && - strcasecmp(StorageMedium,UPNP_STORAGE_MD_PICTURE) && - strcasecmp(StorageMedium,UPNP_STORAGE_MICRO_MV) && - strcasecmp(StorageMedium,UPNP_STORAGE_MINI_DV) && - strcasecmp(StorageMedium,UPNP_STORAGE_NETWORK) && - strcasecmp(StorageMedium,UPNP_STORAGE_SACD) && - strcasecmp(StorageMedium,UPNP_STORAGE_S_VHS) && - strcasecmp(StorageMedium,UPNP_STORAGE_UNKNOWN) && - strcasecmp(StorageMedium,UPNP_STORAGE_VHS) && - strcasecmp(StorageMedium,UPNP_STORAGE_VHSC) && - strcasecmp(StorageMedium,UPNP_STORAGE_VIDEO8) && - strcasecmp(StorageMedium,UPNP_STORAGE_VIDEO_CD) && - strcasecmp(StorageMedium,UPNP_STORAGE_W_VHS) - ){ - ERROR("Invalid storage type: %s", StorageMedium); - return -1; - } - else { - this->mStorageMedium = StorageMedium; - } - return 0; -} - -/**********************************************\ -* * -* Mediator factory * -* * -\**********************************************/ - -cUPnPObjectFactory* cUPnPObjectFactory::mInstance = NULL; - -cUPnPObjectFactory* cUPnPObjectFactory::getInstance(){ - if(!cUPnPObjectFactory::mInstance) - cUPnPObjectFactory::mInstance = new cUPnPObjectFactory(); - - if(cUPnPObjectFactory::mInstance) return cUPnPObjectFactory::mInstance; - else return NULL; -} - -cUPnPObjectFactory::cUPnPObjectFactory(){ - this->mDatabase = cSQLiteDatabase::getInstance(); -} - -void cUPnPObjectFactory::registerMediator(const char* UPnPClass, cMediatorInterface* Mediator){ - if(UPnPClass == NULL){ - ERROR("Class is undefined"); - return; - } - if(Mediator == NULL){ - ERROR("Mediator is undefined"); - return; - } - MESSAGE(VERBOSE_SDK, "Registering mediator for class '%s'", UPnPClass); - this->mMediators[UPnPClass] = Mediator; - MESSAGE(VERBOSE_SDK, "Now %d mediators registered", this->mMediators.size()); - return; -} - -void cUPnPObjectFactory::unregisterMediator(const char* UPnPClass, bool freeMediator){ - if(UPnPClass == NULL){ - ERROR("Class is undefined"); - return; - } - tMediatorMap::iterator MediatorIterator = this->mMediators.find(UPnPClass); - if(MediatorIterator==this->mMediators.end()){ - ERROR("No such mediator found for class '%s'", UPnPClass); - return; - } - MESSAGE(VERBOSE_SDK, "Unregistering mediator for class '%s'", UPnPClass); - this->mMediators.erase(MediatorIterator); - if(freeMediator) delete MediatorIterator->second; - MESSAGE(VERBOSE_SDK, "Now %d mediators registered", this->mMediators.size()); - return; -} - -cMediatorInterface* cUPnPObjectFactory::findMediatorByID(cUPnPObjectID ID){ - cString Format = "SELECT %s FROM %s WHERE %s=%Q"; - cString Column = NULL, Value = NULL, Class = NULL; - cRows* Rows; cRow* Row; - if(this->mDatabase->execStatement(Format, SQLITE_COL_CLASS, SQLITE_TABLE_OBJECTS, SQLITE_COL_OBJECTID, *ID)){ - ERROR("Error while executing statement"); - return NULL; - } - Rows = this->mDatabase->getResultRows(); - if(!Rows->fetchRow(&Row)){ - ERROR("No such object with ID '%s'",*ID); - return NULL; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_CLASS)){ - Class = strdup0(*Value); - } - } - return this->findMediatorByClass(Class); -} - -cMediatorInterface* cUPnPObjectFactory::findMediatorByClass(const char* Class){ - if(!Class){ ERROR("No class specified"); return NULL; } - MESSAGE(VERBOSE_SQL, "Searching for mediator '%s' in %d mediators", Class, this->mMediators.size()); - tMediatorMap::iterator MediatorIterator = this->mMediators.find(Class); - if(MediatorIterator==this->mMediators.end()){ - ERROR("No matching mediator for class '%s'",Class); - return NULL; - } - else { - return MediatorIterator->second; - } -} - -cUPnPClassObject* cUPnPObjectFactory::getObject(cUPnPObjectID ID){ - cMediatorInterface* Mediator = this->findMediatorByID(ID); - if(Mediator) return Mediator->getObject(ID); - else { - return NULL; - } -} - -cUPnPClassObject* cUPnPObjectFactory::createObject(const char* UPnPClass, const char* Title, bool Restricted){ - cMediatorInterface* Mediator = this->findMediatorByClass(UPnPClass); - return Mediator->createObject(Title, Restricted); -} - -int cUPnPObjectFactory::deleteObject(cUPnPClassObject* Object){ - cMediatorInterface* Mediator = this->findMediatorByClass(Object->getClass()); - return Mediator->deleteObject(Object); -} - -int cUPnPObjectFactory::clearObject(cUPnPClassObject* Object){ - cMediatorInterface* Mediator = this->findMediatorByClass(Object->getClass()); - return Mediator->clearObject(Object); -} - -int cUPnPObjectFactory::saveObject(cUPnPClassObject* Object){ - cMediatorInterface* Mediator = this->findMediatorByClass(Object->getClass()); - return Mediator->saveObject(Object); -} - - /**********************************************\ - * * - * Mediators * - * * - \**********************************************/ - - /**********************************************\ - * * - * Object mediator * - * * - \**********************************************/ - -cUPnPObjectMediator::cUPnPObjectMediator(cMediaDatabase* MediaDatabase) : - mMediaDatabase(MediaDatabase){ - this->mDatabase = cSQLiteDatabase::getInstance(); -} - -cUPnPObjectMediator::~cUPnPObjectMediator(){ - delete this->mDatabase; - delete this->mMediaDatabase; -} - -int cUPnPObjectMediator::saveObject(cUPnPClassObject* Object){ - bool succesful = true; - - this->mDatabase->startTransaction(); - if(Object->getID() == -1) succesful = false; - else if(this->objectToDatabase(Object)) succesful = false; - else succesful = true; - - if(succesful){ - this->mDatabase->commitTransaction(); - Object->setModified(); - this->mMediaDatabase->cacheObject(Object); - this->mMediaDatabase->updateSystemID(); - return 0; - } - else { - this->mDatabase->rollbackTransaction(); - return -1; - } - return -1; -} - -int cUPnPObjectMediator::deleteObject(cUPnPClassObject* Object){ - cString Format = "DELETE FROM %s WHERE %s=%Q"; - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_OBJECTS, SQLITE_COL_OBJECTID, *Object->getID())){ - ERROR("Error while executing statement"); - return -1; - } - #ifdef SQLITE_CASCADE_DELETES - this->clearObject(Object); - #endif - delete Object; Object = NULL; - return 0; -} - -int cUPnPObjectMediator::clearObject(cUPnPClassObject* Object){ - cUPnPClassContainer* Container = Object->getContainer(); - if(Container){ - cList<cUPnPClassObject>* List = Container->getObjectList(); - for(cUPnPClassObject* Child = List->First(); Child; Child = List->Next(Child)){ - if(this->deleteObject(Child)) return -1; - } - } - return 0; -} - -int cUPnPObjectMediator::initializeObject(cUPnPClassObject* Object, const char* Class, const char* Title, bool Restricted){ - cUPnPObjectID ObjectID = this->mMediaDatabase->getNextObjectID(); - if(Object->setID(ObjectID)){ - ERROR("Error while setting ID"); - return -1; - } - cUPnPClassObject* Root = this->mMediaDatabase->getObjectByID(0); - if(Root){ - Root->getContainer()->addObject(Object); - } - else { - Object->setParent(NULL); - } - if(Object->setClass(Class)){ - ERROR("Error while setting class"); - return -1; - } - if(Object->setTitle(Title)){ - ERROR("Error while setting title"); - return -1; - } - if(Object->setRestricted(Restricted)){ - ERROR("Error while setting restriction"); - return -1; - } - if(this->mDatabase->execStatement("INSERT INTO %s (%s, %s, %s, %s, %s) VALUES (%s, %s, %Q, %Q, %d)", - SQLITE_TABLE_OBJECTS, - SQLITE_COL_OBJECTID, - SQLITE_COL_PARENTID, - SQLITE_COL_CLASS, - SQLITE_COL_TITLE, - SQLITE_COL_RESTRICTED, - *Object->getID(), - *Object->getParentID(), - Object->getClass(), - Object->getTitle(), - Object->isRestricted()?1:0)){ - ERROR("Error while executing statement"); - return -1; - } - return 0; -} - -cUPnPClassObject* cUPnPObjectMediator::getObject(cUPnPObjectID){ WARNING("Getting instance of class 'Object' forbidden"); return NULL; } - -cUPnPClassObject* cUPnPObjectMediator::createObject(const char*, bool){ WARNING("Getting instance of class 'Object' forbidden"); return NULL; } - -int cUPnPObjectMediator::objectToDatabase(cUPnPClassObject* Object){ - MESSAGE(VERBOSE_MODIFICATIONS, "Updating object #%s", *Object->getID()); - cString Format = "UPDATE %s SET %s WHERE %s='%s'"; - //cString Format = "INSERT OR REPLACE INTO %s (%s) VALUES (%s);"; - cString Set=NULL; - //cString Columns=NULL, Values=NULL; - char *Value=NULL; - cString Properties[] = { - SQLITE_COL_OBJECTID, - SQLITE_COL_PARENTID, - SQLITE_COL_CLASS, - SQLITE_COL_TITLE, - SQLITE_COL_RESTRICTED, - SQLITE_COL_CREATOR, - SQLITE_COL_WRITESTATUS, - NULL - }; - for(cString* Property = Properties; *(*Property)!=NULL; Property++){ - if(!Object->getProperty(*Property, &Value)){ - ERROR("No such property '%s' in object with ID '%s'",*(*Property),*Object->getID()); - return -1; - } - Set = cSQLiteDatabase::sprintf("%s%s%s=%Q", *Set?*Set:"", *Set?",":"", *(*Property), Value); - } - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_OBJECTS, *Set, SQLITE_COL_OBJECTID, *Object->mLastID)){ - ERROR("Error while executing statement"); - return -1; - } - // The update was successful --> the current ID is now also the LastID - Object->mLastID = Object->mID; - return 0; -} - -int cUPnPObjectMediator::databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID){ - cString Column = NULL, Value = NULL; - cRows* Rows; cRow* Row; - if(this->mDatabase->execStatement("SELECT * FROM %s WHERE %s=%Q", - SQLITE_TABLE_OBJECTS, - SQLITE_COL_OBJECTID, - *ID)){ - ERROR("Error while executing statement"); - return -1; - } - Rows = this->mDatabase->getResultRows(); - if(!Rows->fetchRow(&Row)){ - ERROR("No such object with ID '%s'",*ID); - return -1; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_OBJECTID)){ - if(!*Value || Object->setID(atoi(Value))){ - ERROR("Error while setting object ID"); - return -1; - } - this->mMediaDatabase->cacheObject(Object); - } - else if(!strcasecmp(Column, SQLITE_COL_PARENTID)){ - if(*Value){ - cUPnPObjectID RefID = atoi(Value); - cUPnPClassContainer* ParentObject; - if(RefID == -1){ - ParentObject = NULL; - } - else { - ParentObject = (cUPnPClassContainer*)this->mMediaDatabase->getObjectByID(RefID); - if(!ParentObject){ - ERROR("No such parent with ID '%s' found.",*RefID); - return -1; - } - } - Object->setParent(ParentObject); - } - else { - ERROR("Invalid parent ID"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_CLASS)){ - if(!*Value || Object->setClass(Value)){ - ERROR("Error while setting class"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_TITLE)){ - if(!*Value || Object->setTitle(Value)){ - ERROR("Error while setting title"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_RESTRICTED)){ - if(!*Value || Object->setRestricted(atoi(Value)==1?true:false)){ - ERROR("Error while setting restriction"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_CREATOR)){ - if(Object->setCreator(Value)){ - ERROR("Error while setting creator"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_WRITESTATUS)){ - if(*Value && Object->setWriteStatus(atoi(Value))){ - ERROR("Error while setting write status"); - return -1; - } - } - } - cUPnPResources::getInstance()->getResourcesOfObject(Object); - return 0; -} - - /**********************************************\ - * * - * Item mediator * - * * - \**********************************************/ - -cUPnPItemMediator::cUPnPItemMediator(cMediaDatabase* MediaDatabase) : - cUPnPObjectMediator(MediaDatabase){} - -int cUPnPItemMediator::objectToDatabase(cUPnPClassObject* Object){ - if(cUPnPObjectMediator::objectToDatabase(Object)) return -1; - cString Format = "INSERT OR REPLACE INTO %s (%s) VALUES (%s);"; - cString Columns=NULL, Values=NULL; - char *Value=NULL; - cString Properties[] = { - SQLITE_COL_OBJECTID, - SQLITE_COL_REFERENCEID, - NULL - }; - for(cString* Property = Properties; *(*Property); Property++){ - Columns = cSQLiteDatabase::sprintf("%s%s%s", *Columns?*Columns:"", *Columns?",":"", *(*Property)); - if(!Object->getProperty(*Property, &Value)){ - ERROR("No such property '%s' in object with ID '%s'",*(*Property),*Object->getID()); - return -1; - } - Values = cSQLiteDatabase::sprintf("%s%s%Q", *Values?*Values:"", *Values?",":"", Value); - - } - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_ITEMS, *Columns, *Values)){ - ERROR("Error while executing statement"); - return -1; - } - return 0; -} - -int cUPnPItemMediator::databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID){ - if(cUPnPObjectMediator::databaseToObject(Object,ID)){ - ERROR("Error while loading object"); - return -1; - } - cUPnPClassItem* Item = (cUPnPClassItem*) Object; - cString Column = NULL, Value = NULL; - cRows* Rows; cRow* Row; - if(this->mDatabase->execStatement("SELECT * FROM %s WHERE %s=%Q", - SQLITE_TABLE_ITEMS, - SQLITE_COL_OBJECTID, - *ID)){ - ERROR("Error while executing statement"); - return -1; - } - Rows = this->mDatabase->getResultRows(); - if(!Rows->fetchRow(&Row)){ - MESSAGE(VERBOSE_SQL, "No item properties found"); - return 0; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_REFERENCEID)){ - cUPnPObjectID RefID = atoi(Value); - cUPnPClassItem* RefObject; - if(RefID == -1){ - RefObject = NULL; - } - else { - RefObject = (cUPnPClassItem*)this->mMediaDatabase->getObjectByID(RefID); - if(!RefObject){ - ERROR("No such reference item with ID '%s' found.",*RefID); - return -1; - } - } - Item->setReference(RefObject); - } - } - return 0; -} - -cUPnPClassItem* cUPnPItemMediator::getObject(cUPnPObjectID ID){ - MESSAGE(VERBOSE_METADATA, "Getting Item with ID '%s'",*ID); - cUPnPClassItem* Object = new cUPnPClassItem; - if(this->databaseToObject(Object, ID)) return NULL; - return Object; -} - -cUPnPClassItem* cUPnPItemMediator::createObject(const char* Title, bool Restricted){ - MESSAGE(VERBOSE_MODIFICATIONS, "Creating Item '%s'",Title); - cUPnPClassItem* Object = new cUPnPClassItem; - if(this->initializeObject(Object, UPNP_CLASS_ITEM, Title, Restricted)) return NULL; - return Object; -} - - /**********************************************\ - * * - * Container mediator * - * * - \**********************************************/ - -cUPnPContainerMediator::cUPnPContainerMediator(cMediaDatabase* MediaDatabase) : - cUPnPObjectMediator(MediaDatabase){} - -int cUPnPContainerMediator::objectToDatabase(cUPnPClassObject* Object){ - if(cUPnPObjectMediator::objectToDatabase(Object)) return -1; - cUPnPClassContainer* Container = (cUPnPClassContainer*)Object; - cString Format = "INSERT OR REPLACE INTO %s (%s) VALUES (%s);"; - cString Columns=NULL, Values=NULL; - char *Value=NULL; - cString Properties[] = { - SQLITE_COL_OBJECTID, - SQLITE_COL_DLNA_CONTAINERTYPE, - SQLITE_COL_SEARCHABLE, - SQLITE_COL_CONTAINER_UID, - NULL - }; - for(cString* Property = Properties; *(*Property); Property++){ - Columns = cSQLiteDatabase::sprintf("%s%s%s", *Columns?*Columns:"", *Columns?",":"", *(*Property)); - if(!Container->getProperty(*Property, &Value)){ - ERROR("No such property '%s' in object with ID '%s'",*(*Property),*Container->getID()); - return -1; - } - Values = cSQLiteDatabase::sprintf("%s%s%Q", *Values?*Values:"", *Values?",":"", Value); - } - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_CONTAINERS, *Columns, *Values)){ - ERROR("Error while executing statement"); - return -1; - } - for(unsigned int i=0; i<Container->getSearchClasses()->size(); i++){ - cClass Class = Container->getSearchClasses()->at(i); - Columns = cSQLiteDatabase::sprintf("%s,%s,%s", SQLITE_COL_OBJECTID, SQLITE_COL_CLASS, SQLITE_COL_CLASSDERIVED); - Values = cSQLiteDatabase::sprintf("%Q,%Q,%d", *Container->getID(), *Class.ID, Class.includeDerived?1:0); - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_SEARCHCLASS, *Columns, *Values)){ - ERROR("Error while executing statement"); - return -1; - } - } - // Create classes not necessary at the moment - return 0; -} - -int cUPnPContainerMediator::databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID){ - if(cUPnPObjectMediator::databaseToObject(Object,ID)){ - ERROR("Error while loading object"); - return -1; - } - cUPnPClassContainer* Container = (cUPnPClassContainer*)Object; - cString Format = "SELECT * FROM %s WHERE %s=%s"; - cString Column = NULL, Value = NULL; - cRows* Rows; cRow* Row; - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_CONTAINERS, SQLITE_COL_OBJECTID, *ID)){ - ERROR("Error while executing statement"); - return -1; - } - Rows = this->mDatabase->getResultRows(); - if(!Rows->fetchRow(&Row)){ - MESSAGE(VERBOSE_SQL, "No item properties found"); - return 0; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_DLNA_CONTAINERTYPE)){ - if(Container->setContainerType(Value)){ - ERROR("Error while setting container type"); - return -1; - } - } - if(!strcasecmp(Column, SQLITE_COL_CONTAINER_UID)){ - if(Container->setUpdateID((unsigned int)atoi(Value))){ - ERROR("Error while setting update ID"); - return -1; - } - } - if(!strcasecmp(Column, SQLITE_COL_SEARCHABLE)){ - if(Container->setSearchable(atoi(Value)==1?true:false)){ - ERROR("Error while setting searchable"); - return -1; - } - } - } - if(this->mDatabase->execStatement("SELECT %s FROM %s WHERE %s=%s", SQLITE_COL_OBJECTID, - SQLITE_TABLE_OBJECTS, - SQLITE_COL_PARENTID, - *ID)){ - ERROR("Error while executing statement"); - return -1; - } - Rows = this->mDatabase->getResultRows(); - while(Rows->fetchRow(&Row)){ - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_OBJECTID)){ - Container->addObject(this->mMediaDatabase->getObjectByID(atoi(Value))); - } - } - } - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_SEARCHCLASS, SQLITE_COL_OBJECTID, *ID)){ - ERROR("Error while executing statement"); - return -1; - } - std::vector<cClass> SearchClasses; - Rows = this->mDatabase->getResultRows(); - while(Rows->fetchRow(&Row)){ - cClass Class; - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_CLASS)){ - Class.ID = strdup0(*Value); - } - else if(!strcasecmp(Column, SQLITE_COL_CLASSDERIVED)){ - Class.includeDerived = atoi(Value)==1?true:false; - } - } - SearchClasses.push_back(Class); - } - if(Container->setSearchClasses(SearchClasses)){ - ERROR("Error while setting search classes"); - return -1; - } - return 0; -} - -cUPnPClassContainer* cUPnPContainerMediator::createObject(const char* Title, bool Restricted){ - MESSAGE(VERBOSE_MODIFICATIONS, "Creating Container '%s'",Title); - cUPnPClassContainer* Object = new cUPnPClassContainer; - if(this->initializeObject(Object, UPNP_CLASS_CONTAINER, Title, Restricted)) return NULL; - return Object; -} - -cUPnPClassContainer* cUPnPContainerMediator::getObject(cUPnPObjectID ID){ - MESSAGE(VERBOSE_METADATA, "Getting Container with ID '%s'",*ID); - cUPnPClassContainer* Object = new cUPnPClassContainer; - if(this->databaseToObject(Object, ID)) return NULL; - return Object; -} - - /**********************************************\ - * * - * Video item mediator * - * * - \**********************************************/ - -cUPnPVideoItemMediator::cUPnPVideoItemMediator(cMediaDatabase* MediaDatabase) : - cUPnPItemMediator(MediaDatabase){} - -cUPnPClassVideoItem* cUPnPVideoItemMediator::createObject(const char* Title, bool Restricted){ - MESSAGE(VERBOSE_MODIFICATIONS, "Creating Video item '%s'",Title); - cUPnPClassVideoItem* Object = new cUPnPClassVideoItem; - if(this->initializeObject(Object, UPNP_CLASS_VIDEO, Title, Restricted)) return NULL; - return Object; -} - -cUPnPClassVideoItem* cUPnPVideoItemMediator::getObject(cUPnPObjectID ID){ - MESSAGE(VERBOSE_METADATA, "Getting Video item with ID '%s'",*ID); - cUPnPClassVideoItem* Object = new cUPnPClassVideoItem; - if(this->databaseToObject(Object, ID)) return NULL; - return Object; -} - -int cUPnPVideoItemMediator::objectToDatabase(cUPnPClassObject* Object){ - if(cUPnPItemMediator::objectToDatabase(Object)) return -1; - cUPnPClassVideoItem* VideoItem = (cUPnPClassVideoItem*)Object; - cString Format = "INSERT OR REPLACE INTO %s (%s) VALUES (%s);"; - cString Columns=NULL, Values=NULL; - char *Value=NULL; - cString Properties[] = { - SQLITE_COL_OBJECTID, - SQLITE_COL_GENRE, - SQLITE_COL_LONGDESCRIPTION, - SQLITE_COL_PRODUCER, - SQLITE_COL_RATING, - SQLITE_COL_ACTOR, - SQLITE_COL_DIRECTOR, - SQLITE_COL_DESCRIPTION, - SQLITE_COL_PUBLISHER, - SQLITE_COL_LANGUAGE, - SQLITE_COL_RELATION, - NULL - }; - for(cString* Property = Properties; *(*Property); Property++){ - Columns = cSQLiteDatabase::sprintf("%s%s%s", *Columns?*Columns:"", *Columns?",":"", *(*Property)); - if(!VideoItem->getProperty(*Property, &Value)){ - ERROR("No such property '%s' in object with ID '%s'",*(*Property),* VideoItem->getID()); - return -1; - } - Values = cSQLiteDatabase::sprintf("%s%s%Q", *Values?*Values:"", *Values?",":"", Value); - } - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_VIDEOITEMS, *Columns, *Values)){ - ERROR("Error while executing statement"); - return -1; - } - return 0; -} - -int cUPnPVideoItemMediator::databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID){ - if(cUPnPItemMediator::databaseToObject(Object,ID)){ - ERROR("Error while loading object"); - return -1; - } - cUPnPClassVideoItem* VideoItem = (cUPnPClassVideoItem*)Object; - cString Format = "SELECT * FROM %s WHERE %s=%s"; - cString Column = NULL, Value = NULL; - cRows* Rows; cRow* Row; - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_VIDEOITEMS, SQLITE_COL_OBJECTID, *ID)){ - ERROR("Error while executing statement"); - return -1; - } - Rows = this->mDatabase->getResultRows(); - if(!Rows->fetchRow(&Row)){ - MESSAGE(VERBOSE_SQL, "No item properties found"); - return 0; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_GENRE)){ - if(VideoItem->setGenre(Value)){ - ERROR("Error while setting genre"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_LONGDESCRIPTION)){ - if(VideoItem->setLongDescription(Value)){ - ERROR("Error while setting long description"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_PRODUCER)){ - if(VideoItem->setProducers(Value)){ - ERROR("Error while setting producers"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_RATING)){ - if(VideoItem->setRating(Value)){ - ERROR("Error while setting rating"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_ACTOR)){ - if(VideoItem->setActors(Value)){ - ERROR("Error while setting actors"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_DIRECTOR)){ - if(VideoItem->setDirectors(Value)){ - ERROR("Error while setting directors"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_DESCRIPTION)){ - if(VideoItem->setDescription(Value)){ - ERROR("Error while setting description"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_PUBLISHER)){ - if(VideoItem->setPublishers(Value)){ - ERROR("Error while setting publishers"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_LANGUAGE)){ - if(VideoItem->setLanguage(Value)){ - ERROR("Error while setting language"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_RELATION)){ - if(VideoItem->setRelations(Value)){ - ERROR("Error while setting relations"); - return -1; - } - } - } - return 0; -} - - /**********************************************\ - * * - * Video broadcast item mediator * - * * - \**********************************************/ - -cUPnPVideoBroadcastMediator::cUPnPVideoBroadcastMediator(cMediaDatabase* MediaDatabase) : - cUPnPVideoItemMediator(MediaDatabase){} - -cUPnPClassVideoBroadcast* cUPnPVideoBroadcastMediator::createObject(const char* Title, bool Restricted){ - MESSAGE(VERBOSE_MODIFICATIONS, "Creating Video broadcast '%s'",Title); - cUPnPClassVideoBroadcast* Object = new cUPnPClassVideoBroadcast; - if(this->initializeObject(Object, UPNP_CLASS_VIDEOBC, Title, Restricted)) return NULL; - return Object; -} - -cUPnPClassVideoBroadcast* cUPnPVideoBroadcastMediator::getObject(cUPnPObjectID ID){ - MESSAGE(VERBOSE_METADATA, "Getting Video broadcast with ID '%s'",*ID); - cUPnPClassVideoBroadcast* Object = new cUPnPClassVideoBroadcast; - if(this->databaseToObject(Object, ID)) return NULL; - return Object; -} - -int cUPnPVideoBroadcastMediator::objectToDatabase(cUPnPClassObject* Object){ - if(cUPnPVideoItemMediator::objectToDatabase(Object)) return -1; - cUPnPClassVideoBroadcast* VideoBroadcast = (cUPnPClassVideoBroadcast*)Object; - cString Format = "INSERT OR REPLACE INTO %s (%s) VALUES (%s);"; - cString Columns=NULL, Values=NULL; - char *Value=NULL; - cString Properties[] = { - SQLITE_COL_OBJECTID, - SQLITE_COL_ICON, - SQLITE_COL_REGION, - SQLITE_COL_CHANNELNAME, - SQLITE_COL_CHANNELNR, - NULL - }; - for(cString* Property = Properties; *(*Property); Property++){ - Columns = cSQLiteDatabase::sprintf("%s%s%s", *Columns?*Columns:"", *Columns?",":"", *(*Property)); - if(!VideoBroadcast->getProperty(*Property, &Value)){ - ERROR("No such property '%s' in object with ID '%s'",*(*Property),* VideoBroadcast->getID()); - return -1; - } - Values = cSQLiteDatabase::sprintf("%s%s%Q", *Values?*Values:"", *Values?",":"", Value); - } - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_VIDEOBROADCASTS, *Columns, *Values)){ - ERROR("Error while executing statement"); - return -1; - } - return 0; -} - -int cUPnPVideoBroadcastMediator::databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID){ - if(cUPnPVideoItemMediator::databaseToObject(Object,ID)){ - ERROR("Error while loading object"); - return -1; - } - cUPnPClassVideoBroadcast* VideoBroadcast = (cUPnPClassVideoBroadcast*)Object; - cString Format = "SELECT * FROM %s WHERE %s=%s"; - cString Column = NULL, Value = NULL; - cRows* Rows; cRow* Row; - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_VIDEOBROADCASTS, SQLITE_COL_OBJECTID, *ID)){ - ERROR("Error while executing statement"); - return -1; - } - Rows = this->mDatabase->getResultRows(); - if(!Rows->fetchRow(&Row)){ - MESSAGE(VERBOSE_SQL, "No item properties found"); - return 0; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_ICON)){ - if(VideoBroadcast->setIcon(Value)){ - ERROR("Error while setting icon"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_REGION)){ - if(VideoBroadcast->setRegion(Value)){ - ERROR("Error while setting region"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_CHANNELNR)){ - if(VideoBroadcast->setChannelNr(atoi(Value))){ - ERROR("Error while setting channel number"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_CHANNELNAME)){ - if(VideoBroadcast->setChannelName(Value)){ - ERROR("Error while setting channel name"); - return -1; - } - } - } - return 0; -} - -/**********************************************\ -* * -* Movie item mediator * -* * -\**********************************************/ - -cUPnPMovieMediator::cUPnPMovieMediator(cMediaDatabase* MediaDatabase) : - cUPnPVideoItemMediator(MediaDatabase){} - -cUPnPClassMovie* cUPnPMovieMediator::createObject(const char* Title, bool Restricted){ - MESSAGE(VERBOSE_MODIFICATIONS, "Creating movie '%s'",Title); - cUPnPClassMovie* Object = new cUPnPClassMovie; - if(this->initializeObject(Object, UPNP_CLASS_MOVIE, Title, Restricted)) return NULL; - return Object; -} - -cUPnPClassMovie* cUPnPMovieMediator::getObject(cUPnPObjectID ID){ - MESSAGE(VERBOSE_METADATA, "Getting movie with ID '%s'",*ID); - cUPnPClassMovie* Object = new cUPnPClassMovie; - if(this->databaseToObject(Object, ID)) return NULL; - return Object; -} - -int cUPnPMovieMediator::objectToDatabase(cUPnPClassObject* Object){ - if(cUPnPVideoItemMediator::objectToDatabase(Object)) return -1; - cUPnPClassMovie* Movie = (cUPnPClassMovie*)Object; - cString Format = "INSERT OR REPLACE INTO %s (%s) VALUES (%s);"; - cString Columns=NULL, Values=NULL; - char *Value=NULL; - cString Properties[] = { - SQLITE_COL_OBJECTID, - SQLITE_COL_DVDREGIONCODE, - SQLITE_COL_STORAGEMEDIUM, - NULL - }; - for(cString* Property = Properties; *(*Property); Property++){ - Columns = cSQLiteDatabase::sprintf("%s%s%s", *Columns?*Columns:"", *Columns?",":"", *(*Property)); - if(!Movie->getProperty(*Property, &Value)){ - ERROR("No such property '%s' in object with ID '%s'",*(*Property),* Movie->getID()); - return -1; - } - Values = cSQLiteDatabase::sprintf("%s%s%Q", *Values?*Values:"", *Values?",":"", Value); - } - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_MOVIES, *Columns, *Values)){ - ERROR("Error while executing statement"); - return -1; - } - return 0; -} - -int cUPnPMovieMediator::databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID){ - if(cUPnPVideoItemMediator::databaseToObject(Object,ID)){ - ERROR("Error while loading object"); - return -1; - } - cUPnPClassMovie* Movie = (cUPnPClassMovie*)Object; - cString Format = "SELECT * FROM %s WHERE %s=%s"; - cString Column = NULL, Value = NULL; - cRows* Rows; cRow* Row; - if(this->mDatabase->execStatement(Format, SQLITE_TABLE_MOVIES, SQLITE_COL_OBJECTID, *ID)){ - ERROR("Error while executing statement"); - return -1; - } - Rows = this->mDatabase->getResultRows(); - if(!Rows->fetchRow(&Row)){ - MESSAGE(VERBOSE_SQL, "No item properties found"); - return 0; - } - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_DVDREGIONCODE)){ - if(Movie->setDVDRegionCode(atoi(Value))){ - ERROR("Error while setting icon"); - return -1; - } - } - else if(!strcasecmp(Column, SQLITE_COL_STORAGEMEDIUM)){ - if(Movie->setStorageMedium(Value)){ - ERROR("Error while setting region"); - return -1; - } - } - } - return 0; -}
\ No newline at end of file diff --git a/database/resources.cpp b/database/resources.cpp deleted file mode 100644 index 23403d5..0000000 --- a/database/resources.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - * File: resources.cpp - * Author: savop - * - * Created on 30. September 2009, 15:17 - */ - -#include <string.h> -#include <vdr/channels.h> -#include "upnp/dlna.h" -#include <vdr/tools.h> -#include "resources.h" -#include "avdetector.h" - -cUPnPResource::cUPnPResource(){ - this->mBitrate = 0; - this->mBitsPerSample = 0; - this->mColorDepth = 0; - this->mDuration = NULL; - this->mImportURI = NULL; - this->mNrAudioChannels = 0; - this->mProtocolInfo = NULL; - this->mResolution = NULL; - this->mResource = NULL; - this->mResourceID = 0; - this->mSampleFrequency = 0; - this->mSize = 0; - this->mContentType = NULL; -} - -time_t cUPnPResource::getLastModification() const { - time_t Time; - const cRecording* Recording; - const cEvent* Event; - switch(this->mResourceType){ - case UPNP_RESOURCE_CHANNEL: - case UPNP_RESOURCE_URL: - Time = time(NULL); - break; - case UPNP_RESOURCE_RECORDING: - Recording = Recordings.GetByName(this->mResource); - Event = (Recording)?Recording->Info()->GetEvent():NULL; - Time = (Event)?Event->EndTime():time(NULL); - break; - case UPNP_RESOURCE_FILE: - //break; - default: - ERROR("Invalid resource type. This resource might be broken"); - Time = -1; - } - return Time; -} - -cUPnPResources* cUPnPResources::mInstance = NULL; - -cUPnPResources::cUPnPResources(){ - this->mResources = new cHash<cUPnPResource>; - this->mMediator = new cUPnPResourceMediator; - this->mDatabase = cSQLiteDatabase::getInstance(); -} - -cUPnPResources::~cUPnPResources(){ - delete this->mResources; - delete this->mMediator; -} - -cUPnPResources* cUPnPResources::getInstance(){ - if(!cUPnPResources::mInstance) - cUPnPResources::mInstance = new cUPnPResources(); - if(cUPnPResources::mInstance) return cUPnPResources::mInstance; - else return NULL; -} - -int cUPnPResources::loadResources(){ - if(this->mDatabase->execStatement("SELECT %s FROM %s",SQLITE_COL_RESOURCEID,SQLITE_TABLE_RESOURCES)){ - ERROR("Error while executing statement"); - return -1; - } - cRows* Rows = this->mDatabase->getResultRows(); cRow* Row; - cString Column = NULL, Value = NULL; - while(Rows->fetchRow(&Row)){ - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_RESOURCEID)){ - unsigned int ResourceID = (unsigned int)atoi(Value); - this->getResource(ResourceID); - } - } - } - return 0; -} - -int cUPnPResources::getResourcesOfObject(cUPnPClassObject* Object){ - if(this->mDatabase->execStatement("SELECT %s FROM %s WHERE %s=%Q", - SQLITE_COL_RESOURCEID, - SQLITE_TABLE_RESOURCES, - SQLITE_COL_OBJECTID, - *Object->getID())){ - ERROR("Error while executing statement"); - return -1; - } - cRows* Rows = this->mDatabase->getResultRows(); cRow* Row; - cString Column = NULL, Value = NULL; - while(Rows->fetchRow(&Row)){ - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(Column, SQLITE_COL_RESOURCEID)){ - unsigned int ResourceID = (unsigned int)atoi(Value); - Object->addResource(this->getResource(ResourceID)); - } - } - } - return 0; -} - -cUPnPResource* cUPnPResources::getResource(unsigned int ResourceID){ - cUPnPResource* Resource; - if((Resource = this->mResources->Get(ResourceID))){ - MESSAGE(VERBOSE_METADATA, "Found cached resource"); - return Resource; - } - else if((Resource = this->mMediator->getResource(ResourceID))){ - MESSAGE(VERBOSE_METADATA, "Found resource in database"); - this->mResources->Add(Resource, ResourceID); - return Resource; - } - else { - ERROR("No such resource with ID '%d'", ResourceID); - return NULL; - } -} - -int cUPnPResources::createFromRecording(cUPnPClassVideoItem* Object, cRecording* Recording){ - if(!Object || !Recording){ - ERROR("Invalid input arguments"); - return -1; - } - - cAudioVideoDetector* Detector = new cAudioVideoDetector(Recording); - - if(Detector->detectProperties()){ - ERROR("Error while detecting video properties"); - delete Detector; - return -1; - } - - if(!Detector->getDLNAProfile()){ - ERROR("No DLNA profile found for Recording %s", Recording->Name()); - delete Detector; - return -1; - } - - const char* ProtocolInfo = cDlna::getInstance()->getProtocolInfo(Detector->getDLNAProfile()); - - MESSAGE(VERBOSE_METADATA, "Protocol info: %s", ProtocolInfo); - - cString ResourceFile = Recording->FileName(); - cUPnPResource* Resource = this->mMediator->newResource(Object, UPNP_RESOURCE_RECORDING,ResourceFile, Detector->getDLNAProfile()->mime, ProtocolInfo); - Resource->mBitrate = Detector->getBitrate(); - Resource->mBitsPerSample = Detector->getBitsPerSample(); - Resource->mDuration = duration(Detector->getDuration(), AVDETECTOR_TIME_BASE); - Resource->mResolution = (Detector->getWidth() && Detector->getHeight()) ? *cString::sprintf("%dx%d",Detector->getWidth(), Detector->getHeight()) : NULL; - Resource->mSampleFrequency = Detector->getSampleFrequency(); - Resource->mSize = Detector->getFileSize(); - Resource->mNrAudioChannels = Detector->getNumberOfAudioChannels(); - Resource->mImportURI = NULL; - Resource->mColorDepth = 0; - Object->addResource(Resource); - this->mMediator->saveResource(Object, Resource); - this->mResources->Add(Resource, Resource->getID()); - - delete Detector; - return 0; -} - -int cUPnPResources::createFromFile(cUPnPClassItem* , cString ){ - MESSAGE(VERBOSE_SDK, "To be done"); - return -1; -} - -int cUPnPResources::createFromChannel(cUPnPClassVideoBroadcast* Object, cChannel* Channel){ - if(!Object || !Channel){ - ERROR("Invalid input arguments"); - return -1; - } - - cAudioVideoDetector* Detector = new cAudioVideoDetector(Channel); - - if(Detector->detectProperties()){ - ERROR("Cannot detect channel properties"); - delete Detector; - return -1; - } - - if(!Detector->getDLNAProfile()){ - ERROR("No DLNA profile found for Channel %s", *Channel->GetChannelID().ToString()); - delete Detector; - return -1; - } - - const char* ProtocolInfo = cDlna::getInstance()->getProtocolInfo(Detector->getDLNAProfile()); - - MESSAGE(VERBOSE_METADATA, "Protocol info: %s", ProtocolInfo); - - // Index which may be used to indicate different resources with same channel ID - // For instance a different DVB card - // Not used yet. - int index = 0; - - cString ResourceFile = cString::sprintf("%s:%d", *Channel->GetChannelID().ToString(), index); - cUPnPResource* Resource = this->mMediator->newResource(Object, UPNP_RESOURCE_CHANNEL,ResourceFile, Detector->getDLNAProfile()->mime, ProtocolInfo); - Resource->mBitrate = Detector->getBitrate(); - Resource->mBitsPerSample = Detector->getBitsPerSample(); - Resource->mDuration = duration(Detector->getDuration()); - Resource->mResolution = (Detector->getWidth() && Detector->getHeight()) ? *cString::sprintf("%dx%d",Detector->getWidth(), Detector->getHeight()) : NULL; - Resource->mSampleFrequency = Detector->getSampleFrequency(); - Resource->mSize = Detector->getFileSize(); - Resource->mNrAudioChannels = Detector->getNumberOfAudioChannels(); - Resource->mImportURI = NULL; - Resource->mColorDepth = 0; - Object->addResource(Resource); - this->mMediator->saveResource(Object, Resource); - this->mResources->Add(Resource, Resource->getID()); - - delete Detector; - return 0; -} - -cUPnPResourceMediator::cUPnPResourceMediator(){ - this->mDatabase = cSQLiteDatabase::getInstance(); -} - -cUPnPResourceMediator::~cUPnPResourceMediator(){} - -cUPnPResource* cUPnPResourceMediator::getResource(unsigned int ResourceID){ - cUPnPResource* Resource = new cUPnPResource; - Resource->mResourceID = ResourceID; - if(this->mDatabase->execStatement("SELECT * FROM %s WHERE %s=%d", - SQLITE_TABLE_RESOURCES, - SQLITE_COL_RESOURCEID, - ResourceID)){ - ERROR("Error while executing statement"); - return NULL; - } - cRows* Rows = this->mDatabase->getResultRows(); cRow* Row; - if(!Rows->fetchRow(&Row)){ - ERROR("No such resource found"); - return NULL; - } - cString Column = NULL, Value = NULL; - while(Row->fetchColumn(&Column, &Value)){ - if(!strcasecmp(SQLITE_COL_PROTOCOLINFO, Column)){ - Resource->mProtocolInfo = Value; - } - else if(!strcasecmp(SQLITE_COL_RESOURCE, Column)){ - Resource->mResource = Value; - } - else if(!strcasecmp(SQLITE_COL_SIZE, Column)){ - Resource->mSize = (off64_t)(*Value?atol(Value):0); - } - else if(!strcasecmp(SQLITE_COL_DURATION, Column)){ - Resource->mDuration = Value; - } - else if(!strcasecmp(SQLITE_COL_BITRATE, Column)){ - Resource->mBitrate = *Value?atoi(Value):0; - } - else if(!strcasecmp(SQLITE_COL_SAMPLEFREQUENCE, Column)){ - Resource->mSampleFrequency = *Value?atoi(Value):0; - } - else if(!strcasecmp(SQLITE_COL_BITSPERSAMPLE, Column)){ - Resource->mBitsPerSample = *Value?atoi(Value):0; - } - else if(!strcasecmp(SQLITE_COL_NOAUDIOCHANNELS, Column)){ - Resource->mNrAudioChannels = *Value?atoi(Value):0; - } - else if(!strcasecmp(SQLITE_COL_COLORDEPTH, Column)){ - Resource->mColorDepth = *Value?atoi(Value):0; - } - else if(!strcasecmp(SQLITE_COL_RESOLUTION, Column)){ - Resource->mResolution = Value; - } - else if(!strcasecmp(SQLITE_COL_CONTENTTYPE, Column)){ - Resource->mContentType = Value; - } - else if(!strcasecmp(SQLITE_COL_RESOURCETYPE, Column)){ - Resource->mResourceType = *Value?atoi(Value):0; - } - } - return Resource; -} - -int cUPnPResourceMediator::saveResource(cUPnPClassObject* Object, cUPnPResource* Resource){ - - cString Format = "UPDATE %s SET %s=%Q," - "%s=%Q," - "%s=%Q," - "%s=%lld," - "%s=%Q," - "%s=%d," - "%s=%d," - "%s=%d," - "%s=%d," - "%s=%d," - "%s=%Q," - "%s=%Q," - "%s=%d" - " WHERE %s=%d"; - - if(this->mDatabase->execStatement(Format, - SQLITE_TABLE_RESOURCES, - SQLITE_COL_OBJECTID, *Object->getID(), - SQLITE_COL_PROTOCOLINFO, *Resource->mProtocolInfo, - SQLITE_COL_RESOURCE, *Resource->mResource, - SQLITE_COL_SIZE, Resource->mSize, - SQLITE_COL_DURATION, *Resource->mDuration, - SQLITE_COL_BITRATE, Resource->mBitrate, - SQLITE_COL_SAMPLEFREQUENCE, Resource->mSampleFrequency, - SQLITE_COL_BITSPERSAMPLE, Resource->mBitsPerSample, - SQLITE_COL_NOAUDIOCHANNELS, Resource->mNrAudioChannels, - SQLITE_COL_COLORDEPTH, Resource->mColorDepth, - SQLITE_COL_RESOLUTION, *Resource->mResolution, - SQLITE_COL_CONTENTTYPE, *Resource->mContentType, - SQLITE_COL_RESOURCETYPE, Resource->mResourceType, - SQLITE_COL_RESOURCEID, Resource->mResourceID)){ - ERROR("Error while executing statement"); - return -1; - } - - return 0; -} - -cUPnPResource* cUPnPResourceMediator::newResource(cUPnPClassObject* Object, int ResourceType, cString ResourceFile, cString ContentType, cString ProtocolInfo){ - cUPnPResource* Resource = new cUPnPResource; - - if(this->mDatabase->execStatement("INSERT INTO %s (%s,%s,%s,%s,%s) VALUES (%Q,%Q,%Q,%Q,%d)", - SQLITE_TABLE_RESOURCES, - SQLITE_COL_OBJECTID, - SQLITE_COL_RESOURCE, - SQLITE_COL_PROTOCOLINFO, - SQLITE_COL_CONTENTTYPE, - SQLITE_COL_RESOURCETYPE, - *Object->getID(), - *ResourceFile, - *ProtocolInfo, - *ContentType, - ResourceType)){ - ERROR("Error while executing statement"); - return NULL; - } - Resource->mResourceID = (unsigned int)this->mDatabase->getLastInsertRowID(); - Resource->mResource = ResourceFile; - Resource->mProtocolInfo = ProtocolInfo; - Resource->mContentType = ContentType; - Resource->mResourceType = ResourceType; - - return Resource; -}
\ No newline at end of file |