diff options
Diffstat (limited to 'gd_content_interface.c')
-rw-r--r-- | gd_content_interface.c | 1425 |
1 files changed, 0 insertions, 1425 deletions
diff --git a/gd_content_interface.c b/gd_content_interface.c deleted file mode 100644 index 890f2b6..0000000 --- a/gd_content_interface.c +++ /dev/null @@ -1,1425 +0,0 @@ -/*! - * \file gd_content_interface.c - * \brief Data Objects for content (e.g. mp3 files, movies) for the vdr muggle plugin - * \ingroup giantdisc - * - * \version $Revision: 1.27 $ - * \date $Date$ - * \author Ralf Klueber, Lars von Wedel, Andreas Kellner - * \author Responsible author: $Author$ - * - * Implements main classes of for content items and interfaces to SQL databases - * - * This file implements the following classes - * - GdPlaylist a playlist - * - mgGdTrack a single track (content item). e.g. an mp3 file - * - mgSelection a set of tracks (e.g. a database subset matching certain criteria) - */ - -#define DEBUG - -#include "gd_content_interface.h" - -#include "mg_tools.h" -#include "mg_database.h" -#include "vdr_setup.h" - -#include "i18n.h" - -#define GD_PLAYLIST_TYPE 0 //< listtype for giant disc db - -// some dummies to keep the compiler happy -#define DUMMY_CONDITION true // we use that as dummy condition to satisfy C++ syntax -#define DUMMY - -/*! - * \brief initialize a database used by Giantdisc - * - * \todo should be a static function in some Gd class - */ -int GdInitDatabase( MYSQL *db ) -{ - if( mysql_init(db) == NULL ) - { - return -1; - } - - if (the_setup.DbSocket != NULL) - { - mgDebug(1,"Using sockets for connecting to Database."); - - //mgDebug(3,"Socket is: '%s'",the_setup.DbSocket); - //mgDebug(3,"DbUser is: '%s'",the_setup.DbUser); - //mgDebug(3,"DbPassword is: '%s'",the_setup.DbPass); - - if( mysql_real_connect( db, - "", - the_setup.DbUser, - the_setup.DbPass, - the_setup.DbName, - 0, - the_setup.DbSocket, 0 ) == NULL ) - { - return -2; - } // if mysql_real_connect - } //if DbSocket - else - { - mgDebug(1,"Using TCP-host for connecting to Database."); - if( mysql_real_connect( db, - the_setup.DbHost, - the_setup.DbUser, - the_setup.DbPass, - the_setup.DbName, - the_setup.DbPort, - NULL, 0 ) == NULL ) - { - return -2; - } // if mysql_real_connect - } // else (if DbSocket) - - return 0; -} - -std::vector<std::string> *GdGetStoredPlaylists(MYSQL db) -{ - std::vector<std::string>* list = new std::vector<std::string>(); - MYSQL_RES *result; - MYSQL_ROW row; - - result = mgSqlReadQuery(&db, "SELECT title FROM playlist"); - - while( (row = mysql_fetch_row(result) ) != NULL ) - { - list->push_back(row[0]); - } - return list; -} - -gdFilterSets::gdFilterSets() -{ - mgFilter* filter; - std::vector<mgFilter*>* set; - std::vector<std::string>* rating; - m_titles.push_back( tr("Track Search") ); - - // create an initial set of filters with empty values - set = new std::vector<mgFilter*>(); - rating = new std::vector<std::string>(); - rating->push_back("-"); - rating->push_back("O"); - rating->push_back("+"); - rating->push_back("++"); - - // year-from - filter = new mgFilterInt(tr("year (from)"), 1901, 1900, 2100); set->push_back(filter); - - // year-to - filter = new mgFilterInt(tr("year (to)"), 2099, 1900, 2100); set->push_back(filter); - - // title - filter = new mgFilterString(tr("title"), ""); set->push_back(filter); - - // artist - filter = new mgFilterString(tr("artist"), ""); set->push_back(filter); - - // genre - filter = new mgFilterString(tr("genre"), ""); set->push_back(filter); - - // rating. TODO: Currently buggy. LVW - // filter = new mgFilterChoice(tr("rating"), 1, rating); set->push_back(filter); - - m_sets.push_back(set); - - m_titles.push_back(tr("Album Search")); - - set = new std::vector<mgFilter*>(); - // year-from - filter = new mgFilterInt(tr("year (from)"), 1901, 1900, 2100); set->push_back(filter); - // year-to - filter = new mgFilterInt(tr("year (to)"), 2099, 1900, 2100); set->push_back(filter); - // title - filter = new mgFilterString(tr("album title"), ""); set->push_back(filter); - // artist - filter = new mgFilterString(tr("album artist"), ""); set->push_back(filter); - // genre - filter = new mgFilterString(tr("genre"), ""); set->push_back(filter); - // rating - filter = new mgFilterChoice(tr("rating"), 1, rating); set->push_back(filter); - - m_sets.push_back(set); - - m_titles.push_back(tr("Playlist Search")); - - set = new std::vector<mgFilter*>(); - // year-from - filter = new mgFilterInt(tr("year (from)"), 1901, 1900, 2100); set->push_back(filter); - // year-to - filter = new mgFilterInt(tr("year (to)"), 2099, 1900, 2100); set->push_back(filter); - // title - filter = new mgFilterString(tr("playlist title"), ""); set->push_back(filter); - // artist - filter = new mgFilterString(tr("playlist author"), ""); set->push_back(filter); - // title - filter = new mgFilterString(tr("title"), ""); set->push_back(filter); - // artist - filter = new mgFilterString(tr("artist"), ""); set->push_back(filter); - // genre - filter = new mgFilterString(tr("genre"), ""); set->push_back(filter); - // rating - filter = new mgFilterChoice(tr("rating"), 1, rating); set->push_back(filter); - - m_sets.push_back(set); - - m_activeSetId = 0; - m_activeSet = m_sets[m_activeSetId]; -} - -gdFilterSets::~gdFilterSets() -{ - // everything is done in the destructor of the base class -} - -std::string gdFilterSets::computeRestriction(int *viewPrt) -{ - std::string sql_str = "1"; - - switch( m_activeSetId ) - { - case 0: - { - // tracks (flatlist for mountain man ;-)) - *viewPrt = 100; - } break; - case 1: - { - // album -> tracks - *viewPrt = 101; - } break; - case 2: - { - // playlist -> tracks - *viewPrt = 102; - } break; - default: - { - mgWarning( "Ignoring Filter Set %i", m_activeSetId ); - } break; - } - - for( std::vector<mgFilter*>::iterator iter = m_activeSet->begin(); - iter != m_activeSet->end(); - iter++ ) - { - if( (*iter)->isSet() ) - { - if( strcmp((*iter)->getName(), tr("playlist title") ) == 0 ) - { - sql_str = sql_str + " AND playlist.title like '%%" - + (*iter)->getStrVal() + "%%'"; - } - else if(strcmp( (*iter)->getName(), tr("playlist author") ) == 0 ) - { - sql_str = sql_str + " AND playlist.author like '%%" - + (*iter)->getStrVal() + "%%'"; - } - else if(strcmp((*iter)->getName(), tr("album title")) == 0 ) - { - sql_str = sql_str + " AND album.title like '%%" - + (*iter)->getStrVal() + "%%'"; - } - else if(strcmp((*iter)->getName(), tr("album artist")) == 0 ) - { - sql_str = sql_str + " AND album.artist like '%%" - + (*iter)->getStrVal() + "%%'"; - } - else if(strcmp((*iter)->getName(), tr("title")) == 0 ) - { - sql_str = sql_str + " AND tracks.title like '%%" - + (*iter)->getStrVal() + "%%'"; - } - else if(strcmp((*iter)->getName(), tr("artist")) == 0 ) - { - sql_str = sql_str + " AND tracks.artist like '%%" - + (*iter)->getStrVal() + "%%'"; - } - else if(strcmp((*iter)->getName(), tr("genre")) == 0 ) - { - sql_str = sql_str + " AND (genre1.genre like '" - + (*iter)->getStrVal() + "'"; - sql_str = sql_str + " OR genre2.genre like '" - + (*iter)->getStrVal() + "')"; - } - else if(strcmp((*iter)->getName(), tr("year (from)")) == 0 ) - { - sql_str = sql_str + " AND tracks.year >= " + (*iter)->getStrVal(); - } - else if(strcmp((*iter)->getName(), tr("year (to)")) == 0 ) - { - sql_str = sql_str + " AND tracks.year <= " + (*iter)->getStrVal(); - } - else if(strcmp((*iter)->getName(), tr("rating")) == 0 ) - { - if ((*iter)->getStrVal() == "-") - { - sql_str = sql_str + " AND tracks.rating >= 0 "; - } - else if ((*iter)->getStrVal() == "O") - { - sql_str = sql_str + " AND tracks.rating >= 1 "; - } - else if ((*iter)->getStrVal() == "+") - { - sql_str = sql_str + " AND tracks.rating >= 2 "; - } - else if ((*iter)->getStrVal() == "++") - { - sql_str = sql_str + " AND tracks.rating >= 3 "; - } - } - else - { - mgWarning( "Ignoring unknown filter %s", (*iter)->getName() ); - } - } - } - mgDebug(1, "Applying sql std::string %s (view=%d)", sql_str.c_str(), *viewPrt ); - return sql_str; -} - -mgGdTrack mgGdTrack::UNDEFINED = mgGdTrack(); - -mgGdTrack::mgGdTrack( int sqlIdentifier, MYSQL dbase ) -{ - m_uniqID = sqlIdentifier; - m_db = dbase; - m_retrieved = false; -} - -mgGdTrack::mgGdTrack(const mgGdTrack& org) -{ - m_uniqID = org.m_uniqID; - m_db = org.m_db; - m_retrieved = org.m_retrieved; - - if( m_retrieved ) - { - m_artist = org.m_artist; - m_title = org.m_title; - m_mp3file = org.m_mp3file; - m_album = org.m_album; - m_genre = org.m_genre; - m_year = org.m_year; - m_rating = org.m_rating; - m_length = org.m_length; - } -} - -mgGdTrack::~mgGdTrack() -{ - // nothing to be done -} - -bool mgGdTrack::readData() -{ - MYSQL_RES *result; - int nrows, nfields; - - // note: this does not work with empty album or genre fields - result = mgSqlReadQuery( &m_db, - "SELECT tracks.artist, album.title, tracks.title, " - "tracks.mp3file, genre.genre, tracks.year, " - "tracks.rating, tracks.length, tracks.samplerate, tracks.channels, tracks.bitrate " - "FROM tracks, album, genre " - "WHERE tracks.id = %d " - "AND album.cddbid = tracks.sourceid AND " - "genre.id = tracks.genre1", - m_uniqID ); - - nrows = mysql_num_rows(result); - nfields = mysql_num_fields(result); - - if( nrows == 0 ) - { - mgWarning( "No entries found \n" ); - return false; - } - else - { - if( nrows > 1 ) - { - mgWarning("mgGdTrack::readData: More than one entry found. Using first entry."); - } - - MYSQL_ROW row = mysql_fetch_row( result ); - - m_artist = row[0]; - m_album = row[1]; - m_title = row[2]; - m_mp3file = std::string( the_setup.ToplevelDir ) + row[3]; - m_genre = row[4]; - - if( sscanf( row[5], "%d", &m_year) != 1 ) - { - mgError("Invalid year '%s' in database", row [5]); - } - - if( row[6] && sscanf( row[6], "%d", &m_rating ) != 1 ) - { - mgError( "Invalid rating '%s' in database", row [6] ); - } - - if( row[7] && sscanf( row[7], "%d", &m_length) != 1 ) - { - mgError( "Invalid duration '%s' in database", row [7]); - } - - if( row[8] && sscanf( row[8], "%d", &m_samplerate ) != 1 ) - { - mgError( "Invalid samplerate '%s' in database", row [7]); - } - - if( row[9] && sscanf( row[9], "%d", &m_channels ) != 1 ) - { - mgError( "Invalid channels '%s' in database", row [7]); - } - - m_bitrate = row[10]; - - } - m_retrieved = true; - return true; -} - -std::string mgGdTrack::getSourceFile() -{ - if( !m_retrieved ) - { - readData(); - } - return m_mp3file; -} - -std::string mgGdTrack::getTitle() -{ - if( !m_retrieved ) - { - readData(); - } - return m_title; -} - -std::string mgGdTrack::getArtist() -{ - if(!m_retrieved) - { - readData(); - } - return m_artist; -} - -int mgGdTrack::getLength() -{ - if( !m_retrieved ) - { - readData(); - } - return m_length; -} - - -std::string mgGdTrack::getLabel(int col) -{ - if( !m_retrieved ) - { - readData(); - } - switch(col) - { - case 0: - return m_title; - case 1: - return m_artist; - case 2: - return m_album; - case 3: - return m_genre; - default: - return ""; - } -} - -std::vector<mgFilter*> *mgGdTrack::getTrackInfo() -{ - return new std::vector<mgFilter*>(); -} - -bool mgGdTrack::setTrackInfo(std::vector<mgFilter*> *info) -{ - return false; -} - -std::string mgGdTrack::getAlbum() -{ - if( !m_retrieved ) - { - readData(); - } - return m_album; -} - -std::string mgGdTrack::getGenre() -{ - if(!m_retrieved) - { - readData(); - } - return m_genre; -} - -int mgGdTrack::getYear() -{ - if(!m_retrieved) - { - readData(); - } - return m_year; -} - -int mgGdTrack::getRating() -{ - if(!m_retrieved) - { - readData(); - } - return m_rating; -} - -int mgGdTrack::getDuration() -{ - if(!m_retrieved) - { - readData(); - } - return m_rating; -} - -int mgGdTrack::getSampleRate() -{ - if(!m_retrieved) - { - readData(); - } - return m_samplerate; -} - -int mgGdTrack::getChannels() -{ - if(!m_retrieved) - { - readData(); - } - return m_channels; -} - -std::string mgGdTrack::getBitrate() -{ - if(!m_retrieved) - { - readData(); - } - return m_bitrate; -} - -std::string mgGdTrack::getImageFile() -{ - return "dummyImg.jpg"; -} - -void mgGdTrack::setTitle(std::string new_title) -{ - m_title = new_title; -} - -void mgGdTrack::setArtist(std::string new_artist) -{ - m_artist = new_artist; -} - -void mgGdTrack::setAlbum(std::string new_album) -{ - m_album = new_album; -} - -void mgGdTrack::setGenre(std::string new_genre) -{ - m_genre = new_genre; -} - -void mgGdTrack::setYear(int new_year) -{ - m_year = new_year; -} - -void mgGdTrack::setRating(int new_rating) -{ - m_rating = new_rating; -} - -bool mgGdTrack::writeData() -{ - mgSqlWriteQuery( &m_db, "UPDATE tracks " - "SET artist=\"%s\", title=\"%s\", year=%d, rating=%d " - "WHERE id=%d", - m_artist.c_str(), m_title.c_str(), - m_year, m_rating, m_uniqID); - return true; -} - -GdTracklist::GdTracklist(MYSQL db_handle, std::string restrictions) -{ - MYSQL_RES *result; - MYSQL_ROW row; - int trackid; - - result = mgSqlReadQuery( &db_handle, - "SELECT tracks.id " - " FROM tracks, album, genre WHERE %s" - " AND album.cddbid=tracks.sourceid " - " AND genre.id=tracks.genre1", - restrictions.c_str()); - - while( ( row = mysql_fetch_row(result) ) != NULL ) - { - // row[0] is the trackid - if(sscanf(row[0], "%d", &trackid) != 1) - { - mgError("Can not extract integer track id from '%s'", - row[0]); - } - m_list.push_back(new mgGdTrack(trackid, db_handle)); - } -} - -GdPlaylist::GdPlaylist(std::string listname, MYSQL db_handle) -{ - MYSQL_RES *result; - MYSQL_ROW row; - int nrows; - - m_db = db_handle; - - // - // check, if the playlist already exists - // - result = mgSqlReadQuery(&m_db, - "SELECT id,author FROM playlist where title=\"%s\"", - listname.c_str()); - nrows = mysql_num_rows(result); - - if( nrows == 0 ) - { - mgDebug(3, "No playlist with name %s found. Creating new playlist\n", - listname.c_str()); - - // create new database entry - mgSqlWriteQuery( &m_db, "INSERT into playlist " - "SET title=\"%s\", author=\"%s\"", - listname.c_str(), - "VDR", // default author - ""); // creates current time as timestamp - m_author = "VDR"; - m_listname = listname; - - // now read thenew list to get the id - result = mgSqlReadQuery( &m_db, - "SELECT id,author FROM playlist where title=\"%s\"", - listname.c_str() ); - nrows = mysql_num_rows(result); - row = mysql_fetch_row(result); - - if( sscanf(row [0], "%d", & m_sqlId) !=1 ) - { - mgError("Invalid id '%s' in database", row [5]); - } - } - else - { // playlist exists, read data - row = mysql_fetch_row(result); - - if( sscanf(row[0], "%d", & m_sqlId) !=1 ) - { - mgError("Invalid id '%s' in database", row [5]); - } - - m_author = row[1]; - m_listname = listname; - - // now read allentries of the playlist and - // write them into the tracklist - insertDataFromSQL(); - - } // end 'else (playlist exists) - - m_listtype = GD_PLAYLIST_TYPE; // GiantDB list type for playlists -} - -GdPlaylist::~GdPlaylist() -{ -} - -void GdPlaylist::setListname(std::string name) -{ - m_listname = name; - m_sqlId = -1; -} - -int GdPlaylist::insertDataFromSQL() -{ - MYSQL_RES *result; - MYSQL_ROW row; - mgGdTrack* trackptr; - int id; - int nrows; - - result = mgSqlReadQuery( &m_db, - "SELECT tracknumber, trackid FROM playlistitem " - "WHERE playlist = %d ORDER BY tracknumber", - m_sqlId); - nrows = mysql_num_rows(result); - while( (row = mysql_fetch_row(result) ) != NULL ) - { - // add antry to tracklist - if( sscanf( row[1], "%d", &id ) !=1 ) - { - mgWarning( "Track id '%s' is not an integer. Ignoring \n", row[1] ); - } - else - { - trackptr = new mgGdTrack( id, m_db ); - m_list.push_back( trackptr ); - } - } - return nrows; -} - -bool GdPlaylist::storePlaylist() -{ - std::vector<mgContentItem*>::iterator iter; - int num; - MYSQL_RES *result; - MYSQL_ROW row; - int nrows; - - if( m_listname == " " ) - { - mgWarning("Can not store Tracklist without name"); - return false; - } - - if( m_sqlId >= 0 ) - { - // playlist alreay exists in SQL database - // remove old items first - // cout << " GdPlaylist::storePlaylist: removing items from " << m_sqlId << flush; - - // remove old playlist items from db - mgSqlWriteQuery(&m_db, - "DELETE FROM playlistitem WHERE playlist = %d", - m_sqlId); - } - else - { - // create new database entry - mgSqlWriteQuery(&m_db, "INSERT into playlist " - "SET title=\"%s\", author=\"%s\"", - m_listname.c_str(), - "VDR", // default author - ""); // creates current time as timestamp - m_author = "VDR"; - - // now read the new list to get the id - result = mgSqlReadQuery( &m_db, - "SELECT id,author FROM playlist where title=\"%s\"", - m_listname.c_str()); - nrows = mysql_num_rows(result); - row = mysql_fetch_row(result); - - if( sscanf( row [0], "%d", & m_sqlId ) !=1 ) - { - mgError("Invalid id '%s' in database", row [5]); - } - } - - // add new playlist items to db - for( iter=m_list.begin(), num=0; - iter != m_list.end(); - iter++, num++) - { - mgSqlWriteQuery(&m_db, - "INSERT into playlistitem " - "SET tracknumber=\"%d\", trackid=\"%d\", playlist=%d", - num, (*iter)->getId(), m_sqlId); - } - return true; -} - -bool GdPlaylist::storeAs( std::string name ) -{ - int id; - MYSQL_ROW row; - MYSQL_RES *result; - - mgDebug( 1, "GdPlaylist::storeAs" ); - - result = mgSqlReadQuery( &m_db, - "SELECT id FROM playlist WHERE title=\"%s\"", - name.c_str() ); - - if( mysql_num_rows(result) ) - { - row = mysql_fetch_row( result ); - mgDebug( 1, "GdPlaylist::storeAs: found playlist" ); - } - else - { - // otherwise create a new database entry - mgSqlWriteQuery( &m_db, "INSERT into playlist SET " - "title=\"%s\", author=\"VDR\"", - name.c_str() ); - - // now read the new list to get the id - result = mgSqlReadQuery( &m_db, - "SELECT id,author FROM playlist where title=\"%s\"", - name.c_str() ); - - row = mysql_fetch_row(result); - mgDebug( 1, "GdPlaylist::storeAs: created playlist" ); - } - - if( sscanf( row [0], "%d", &id ) !=1 ) - { - mgError("Invalid id '%s' in database", row [5]); - } - else - { - // now we know that the playlist 'name' has identifier id - - // remove old playlist items from db - mgSqlWriteQuery( &m_db, - "DELETE FROM playlistitem WHERE playlist = %d", - id ); - - // add new playlist items to db - std::vector<mgContentItem*>::iterator iter; - int num = 0; - for( iter=m_list.begin(), num=0; - iter != m_list.end(); - iter++, num++) - { - mgDebug( 1, "GdPlaylist::storeAs: inserting track" ); - mgSqlWriteQuery(&m_db, - "INSERT into playlistitem " - "SET tracknumber=\"%d\", trackid=\"%d\", playlist=%d", - num, (*iter)->getId(), id ); - } - } - return true; -} - -/*! - * \brief returns the total duration of all songs in the list in seconds - */ -int GdPlaylist::getPlayTime() -{ - //DUMMY - // go over all entries in the playlist and accumulate their playtime - - return 0; -} - -/*! - * \brief returns the duration of all remaining songs in the list in seconds - */ -int GdPlaylist::getPlayTimeRemaining() -{ - //DUMMY - // go over all remaining entries in the playlist and accumulate their - // playtime - // The remaining playtime of the current song is only known by the mplayer - return 0; // dummy -} - -/*! - * \brief constructor - */ -GdTreeNode::GdTreeNode(MYSQL db, int view, std::string filters) - : mgSelectionTreeNode(db, view) -{ - // create a root node - // everything is done in the parent class - m_restriction = filters; - m_view = view; - m_label = tr("Browser"); -} - -GdTreeNode::GdTreeNode( mgSelectionTreeNode* parent, - std::string id, - std::string label, - std::string restriction ) - : mgSelectionTreeNode(parent, id, label) -{ - m_restriction = restriction; - // everything else is done in the parent class -} - -/*! - * \brief destructor - */ -GdTreeNode::~GdTreeNode() -{ - // _children.clear(); -} - -/*! - * \brief checks if this node can be further expandded or not - * \true, if node ia leaf node, false if node can be expanded - */ -bool GdTreeNode::isLeafNode() -{ - if( m_level == 0 ) - { - return false; - } - - switch(m_view) - { - case 1: // artist -> album -> title - if( m_level <= 3 ) - { - return false; - } - break; - case 2: // genre -> artist -> album -> track - if( m_level <= 3 ) - { - return false; - } - break; - case 3: // Artist -> Track - if( m_level <= 2 ) - { - return false; - } - break; - case 4: - if( m_level <= 2 ) - { - return false; - } - break; - case 5: - if( m_level <= 1 ) - { - return false; - } - break; - case 100: - if( m_level <= 0 ) - { - return false; - } - break; - case 101: - if( m_level <= 1 ) - { - return false; - } - break; - case 102: - if( m_level <= 1 ) - { - return false; - } - break; - default: - mgError("View '%d' not yet implemented", m_view); - } - return true; -} - -/*! - * \brief compute children on the fly - * - * \return: true, if the node could be expanded (or was already), false,of - * node can not be expanded any further - * - * retrieves all entries for the next level that satisfy the restriction of - * the current level and create a child-arc for each distinct entry - * - * \todo use asnprintf! - */ -bool GdTreeNode::expand() -{ - MYSQL_ROW row; - MYSQL_RES *result; - int nrows; - int nfields; - char sqlbuff[1024]; /* hope it's big enough ! */ - char idbuf[255]; - int numchild; - - std::string labelfield; // human readable db field for the column to be expanded - std::string idfield; // unique id field for the column to be expanded - std::string new_restriction_field; // field to be restricted by the new level - std::string new_restriction; // complete restriction str for the current child - std::string new_label; - GdTreeNode* new_child; - - std::string tables; // stores the db tables used - -#define FROMJOIN " FROM tracks, genre as genre1, genre as genre2, album WHERE tracks.sourceid=album.cddbid AND genre1.id=tracks.genre1 AND genre2.id=tracks.genre2 AND %s " - - if( m_expanded ) - { - mgWarning("Node already expanded\n"); - return true; - } - - if( m_level == 1 && m_view < 100 ) - { - m_view = atoi( m_id.c_str() ); - } - - mgDebug( 5, "Expanding level %d view %d\n", m_level, m_view ); - if( m_level > 0 ) - { - switch( m_view ) - { - case 1: - { // artist -> album -> title - if( m_level == 1 ) - { - sprintf( sqlbuff, - "SELECT DISTINCT album.artist,album.artist" - FROMJOIN - " ORDER BY album.artist" - , m_restriction.c_str() ); - idfield = "album.artist"; - } - else if( m_level == 2 ) - { // artist -> album - sprintf(sqlbuff, - "SELECT DISTINCT album.title,album.cddbid" - FROMJOIN - " ORDER BY album.title" - , m_restriction.c_str() ); - idfield = "album.cddbid"; - } - else if(m_level == 3) - { // album -> title - sprintf(sqlbuff, - "SELECT tracks.title,tracks.id" - FROMJOIN - " ORDER BY tracks.tracknb" - , m_restriction.c_str() ); - idfield = "tracks.id"; - } - else - { - mgWarning("View #%d level %d' not yet implemented", m_view, m_level); - m_expanded = false; - return false; - } - } break; - case 2: - { // genre -> artist -> album -> track - if( m_level == 1 ) - { // genre - sprintf(sqlbuff, - "SELECT DISTINCT genre1.genre,tracks.genre1" - FROMJOIN - " ORDER BY genre1.id" - , m_restriction.c_str()); - idfield = "tracks.genre1"; - } - else if( m_level == 2 ) - { // genre -> artist - sprintf(sqlbuff, - "SELECT DISTINCT album.artist,album.artist" - FROMJOIN - " ORDER BY album.artist", - m_restriction.c_str()); - idfield = "album.artist"; - } - else if( m_level == 3 ) - { // genre -> artist -> album - sprintf(sqlbuff, - "SELECT DISTINCT album.title,tracks.sourceid" - FROMJOIN - " ORDER BY album.title" - , m_restriction.c_str()); - idfield = "tracks.sourceid"; - } - else if( m_level == 4 ) - { // genre -> artist -> album -> track - sprintf(sqlbuff, - "SELECT DISTINCT tracks.title, tracks.id" - FROMJOIN - " ORDER BY tracks.tracknb" - , m_restriction.c_str()); - idfield = "tracks.id"; - } - else - { - mgWarning("View #%d level %d' not yet implemented", m_view, m_level); - m_expanded = false; - return false; - } - } break; - case 3: - { // Artist -> Track - if( m_level ==1 ) - { - sprintf( sqlbuff, - "SELECT DISTINCT tracks.artist,tracks.artist" - FROMJOIN - " ORDER BY tracks.artist", - m_restriction.c_str()); - idfield = "tracks.artist"; - } - else if( m_level == 2) - { // Track - sprintf(sqlbuff, - "SELECT DISTINCT tracks.title,tracks.id" - FROMJOIN - " ORDER BY tracks.title", - m_restriction.c_str()); - idfield = "tracks.id"; - } - else - { - mgWarning("View #%d level %d' not yet implemented", m_view, m_level); - m_expanded = false; - return false; - } - } break; - case 4: - { // Genre -> Year -> Track - if( m_level == 1 ) - { // Genre - sprintf(sqlbuff, - "SELECT DISTINCT genre1.genre,tracks.genre1" - FROMJOIN - " ORDER BY genre1.genre", - m_restriction.c_str()); - idfield = "tracks.genre1"; - } - else if (m_level == 2) - { // Year - sprintf(sqlbuff, - "SELECT DISTINCT tracks.year,tracks.year" - FROMJOIN - " ORDER BY tracks.year" - , m_restriction.c_str()); - idfield = "tracks.year"; - } - else if( m_level == 3 ) - { // Track - sprintf(sqlbuff, - "SELECT DISTINCT" - " CONCAT(tracks.artist,' - ',tracks.title) AS title" - " ,tracks.id" - FROMJOIN - " ORDER BY title", - //" ORDER BY tracks.title", - m_restriction.c_str()); - idfield = "tracks.id"; - } - else - { - mgWarning("View #%d level %d' not yet implemented", m_view, m_level); - m_expanded = false; - return false; - } - } break; - case 5: // Album -> Tracks - if( m_level == 1 ) - { // Album - sprintf(sqlbuff, - "SELECT DISTINCT" - " CONCAT(album.artist,' - ',album.title) AS title," - " album.cddbid" - FROMJOIN - " ORDER BY title" - , m_restriction.c_str()); - idfield = "tracks.sourceid"; - } - else if (m_level == 2) - { // Track - sprintf(sqlbuff, - "SELECT DISTINCT tracks.title, tracks.id" - FROMJOIN - " ORDER BY tracks.tracknb", - m_restriction.c_str()); - idfield = "tracks.id"; - } - else - { - mgWarning("View #%d level %d' not yet implemented", m_view, m_level); - m_expanded = false; - return false; - } - break; - case 100: - if (m_level == 1) - { - sprintf(sqlbuff, - "SELECT CONCAT(tracks.artist,' - ',tracks.title)," - " tracks.id" - FROMJOIN - " ORDER BY CONCAT(tracks.artist,' - ',tracks.title)" - , m_restriction.c_str()); - idfield = "tracks.id"; - } - else - { - mgWarning( "View #%d level %d' not yet implemented", m_view, m_level ); - m_expanded = false; - return false; - } - break; - case 101: - { // Albumsearch result - if( m_level == 1 ) - { - sprintf(sqlbuff, - "SELECT DISTINCT" - " CONCAT(album.artist,' - ',album.title) as title," - " album.cddbid" - FROMJOIN - " ORDER BY CONCAT(album.artist,' - ',album.title)", - m_restriction.c_str()); - idfield = "tracks.sourceid"; - } - else if( m_level == 2 ) - { - sprintf(sqlbuff, - "SELECT tracks.title,tracks.id" - FROMJOIN - " ORDER BY tracks.tracknb", - m_restriction.c_str()); - idfield = "tracks.id"; - } - else - { - mgWarning("View #%d level %d' not yet implemented", m_view, m_level); - m_expanded = false; - return false; - } - } break; - case 102: - { - if (m_level == 1) - { - sprintf(sqlbuff, - "SELECT DISTINCT playlist.title," - " playlist.id" - " FROM playlist,playlistitem,tracks,genre as genre1,genre as genre2" - " WHERE playlist.id=playlistitem.playlist AND" - " playlistitem.trackid=tracks.id AND" - " genre1.id=tracks.genre1 AND" - " genre2.id=tracks.genre2 AND" - " %s" - " ORDER BY playlist.title,", - m_restriction.c_str()); - idfield = "playlist.id"; - } - else if (m_level == 2) - { - sprintf(sqlbuff, - "SELECT CONCAT(tracks.artist,' - ',tracks.title)," - " tracks.id" - " FROM playlist,playlistitem,tracks" - " WHERE playlist.id=playlistitem.playlist AND" - " playlistitem.trackid=tracks.id AND" - " %s" - " ORDER BY playlistitem.tracknumber", - m_restriction.c_str()); - idfield = "tracks.id"; - } - else - { - mgWarning("View #%d level %d' not yet implemented", m_view, m_level); - m_expanded = false; - return false; - } - } break; - default: - { - mgError("View '%d' not yet implemented", m_view); - } - } - - // now get all childrean of the current node fromthe database - result = mgSqlReadQuery( &m_db, sqlbuff ); - nrows = mysql_num_rows( result ); - nfields = mysql_num_fields(result); - - numchild = 1; - while( (row = mysql_fetch_row(result) ) != NULL ) - { - // row[0] is the printable label for the new child - // row[1] is the unique id for the new child - sprintf( idbuf, "%s_%03d", m_id.c_str(), numchild ); - - // Zweite ebene zeigt alle Tracks des Albums und nicht nur - // diese die den Filterkriterien entsprechen. - // das betrifft nur die Search Views! - - std::string row0 = mgDB::escape_string( &m_db, std::string( row[0] ) ); - std::string row1 = mgDB::escape_string( &m_db, std::string( row[1] ) ); - - if( m_view < 100 ) - { - new_restriction = m_restriction + " AND " - + idfield + "='" + row1 + "'"; - } - else - { - new_restriction = idfield + "='" + row1 + "'"; - } - - new_child = new GdTreeNode(this, // parent - (std::string) idbuf, // id - // row[0], // label, - row0, - new_restriction); - m_children.push_back(new_child); - numchild++; - } - } - else if (m_view <100) - { - new_child = new GdTreeNode(this, // parent - "1" , // id - tr("Artist -> Album -> Track"), // label, - m_restriction); - m_children.push_back(new_child); - new_child = new GdTreeNode(this, // parent - "2" , // id - tr("Genre -> Artist -> Album -> Track") , // label, - m_restriction); - m_children.push_back(new_child); - new_child = new GdTreeNode(this, // parent - "3" , // id - tr("Artist -> Track") , // label, - m_restriction); - m_children.push_back(new_child); - new_child = new GdTreeNode(this, // parent - "4" , // id - tr("Genre -> Year -> Track") , // label, - m_restriction); - m_children.push_back(new_child); - new_child = new GdTreeNode(this, // parent - "5" , // id - tr("Album -> Track") , // label, - m_restriction); - m_children.push_back(new_child); - } - else - { - new_child = new GdTreeNode(this, // parent - "" , // id - tr("Search Result"), // label, - m_restriction); - m_children.push_back(new_child); - } - - m_expanded = true; - mgDebug(5, "%d children expanded\n", m_children.size()); - return true; -} - -/*! - * \brief iterate all children recursively to find the tracks - */ -std::vector<mgContentItem*>* GdTreeNode::getTracks() -{ - MYSQL_ROW row; - MYSQL_RES *result; - int nrows; - int nfields; - std::vector<mgContentItem*>* retlist; - int trackid; - - retlist = new std::vector<mgContentItem*>(); - - // get all tracks satisying the restrictions of this node - mgDebug(5, "getTracks(): query '%s'", m_restriction.c_str()); - - result = mgSqlReadQuery(&m_db, - "SELECT tracks.id FROM tracks, album, genre WHERE %s" - " AND album.cddbid=tracks.sourceid AND genre.id=tracks.genre1", - m_restriction.c_str()); - nrows = mysql_num_rows(result); - nfields = mysql_num_fields(result); - - while((row = mysql_fetch_row(result)) != NULL) - { - // row[0] is the trackid - if(sscanf(row[0], "%d", &trackid) != 1) - { - mgError("Can not extract integer track id from '%s'", - row[0]); - } - retlist->push_back(new mgGdTrack(trackid, m_db)); - } - return retlist; -} - - -/*! - ***************************************************************************** - * \brief returns the first track matchin the restrictions of this node - * assuming we are in a leaf node, this returns the track represented by the - * the leaf - ****************************************************************************/ -mgContentItem* GdTreeNode::getSingleTrack() -{ - MYSQL_ROW row; - MYSQL_RES *result; - int nrows; - int nfields; - mgContentItem* track = NULL; - int trackid; - - // get all tracks satisying the restrictions of this node - mgDebug(5, "getTracks(): query '%s'", m_restriction.c_str()); - - result = mgSqlReadQuery(&m_db, - "SELECT tracks.id FROM tracks, album, genre WHERE %s" - " AND album.cddbid=tracks.sourceid AND genre.id=tracks.genre1", - m_restriction.c_str()); - nrows = mysql_num_rows(result); - nfields = mysql_num_fields(result); - - if( nrows != 1 ) - { - mgWarning( "GdTreeNode::getSingleTrack() :SQL call returned %d tracks, using only the first", - nrows ); - } - // get the first row - if( ( row = mysql_fetch_row(result)) != NULL ) - { - // row[0] is the trackid - if(sscanf(row[0], "%d", &trackid) != 1) - { - mgError("Can not extract integer track id from '%s'", - row[0]); - } - track = new mgGdTrack(trackid, m_db); - } - return track; -} - |