diff options
-rw-r--r-- | TODO | 18 | ||||
-rw-r--r-- | gd_content_interface.c | 261 | ||||
-rw-r--r-- | gd_content_interface.h | 254 | ||||
-rw-r--r-- | mg_tools.h | 33 |
4 files changed, 310 insertions, 256 deletions
@@ -1,6 +1,14 @@ TODO File for Muggle ==================== +- Script to publish a version + - Checkout + - make dist + - copy .tgz, README, CHANGES, HISTORY into web directory + - generate documentation + - copy into web directory + - sync with web + Testing/bugs ============ - Test execution of playlist commands @@ -33,14 +41,15 @@ Code polishing - mgDatabase is not used? - should handle a static object with a MySQL connection - execute queries? - - - mgPlayer used what for? - Could save IP/host name and associate last playlist loaded - Check for unnecessary log commands - Generate HTML documentation using doxygen, - use dotty/gv for state machines of player + - use dotty/gv for state machines of player + - make available online + - Check compatibility for 1.3.12 Short term items @@ -137,10 +146,15 @@ Already Done - create tracklist from filter - create tree from filter - i18n (english and german) +- Album import + - Various artists ************************************************************ * * $Log: TODO,v $ +* Revision 1.14 2004/08/30 14:31:43 LarsAC +* Documentation added +* * Revision 1.13 2004/08/27 15:20:33 LarsAC * Updated open issues w.r.t. import * diff --git a/gd_content_interface.c b/gd_content_interface.c index 06dd35a..8df7c48 100644 --- a/gd_content_interface.c +++ b/gd_content_interface.c @@ -1,8 +1,8 @@ /*! \file gd_content_interface.c * \brief Data Objects for content (e.g. mp3 files, movies) for the vdr muggle plugin * - * \version $Revision: 1.26 $ - * \date $Date: 2004/08/27 15:19:34 $ + * \version $Revision: 1.27 $ + * \date $Date: 2004/08/30 14:31:43 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner * \author Responsible author: $Author: LarsAC $ * @@ -14,7 +14,7 @@ * - mgSelection a set of tracks (e.g. a database subset matching certain criteria) * */ -/*******************************************************************/ + #define DEBUG #include "gd_content_interface.h" @@ -263,11 +263,6 @@ mgGdTrack::mgGdTrack(int sqlIdentifier, MYSQL dbase) } -/*! - ***************************************************************************** - * \brief copy constructor - * - ****************************************************************************/ mgGdTrack::mgGdTrack(const mgGdTrack& org) { m_uniqID = org.m_uniqID; @@ -285,26 +280,11 @@ mgGdTrack::mgGdTrack(const mgGdTrack& org) } } - -/*! - ***************************************************************************** - * \brief destructor - * - ****************************************************************************/ mgGdTrack::~mgGdTrack() { // nothing to be done } -/*! - ***************************************************************************** - * \brief accesses the database to fill the actual data fields - * - * In order to avoid innecessary queries to the database, the content fields - * of the mgGdTrack object may not be filled upon creation. - * As soon as the first content field is needed, this private function - * is called to fill all content fields at once - ****************************************************************************/ bool mgGdTrack::readData() { MYSQL_RES *result; @@ -363,42 +343,24 @@ bool mgGdTrack::readData() return true; } -/*! - ***************************************************************************** - * \brief returns value for _mp3file - * - * If value has not been retrieved from the database, radData() is called first - ****************************************************************************/ string mgGdTrack::getSourceFile() { - if(!m_retrieved) - { + if( !m_retrieved ) + { readData(); - } + } return m_mp3file; } -/*! - ***************************************************************************** - * \brief returns value for m_title - * - * If value has not been retrieved from the database, radData() is called first - ****************************************************************************/ string mgGdTrack::getTitle() { - if(!m_retrieved) + if( !m_retrieved ) { - readData(); + readData(); } - return m_title; + return m_title; } -/*! - ***************************************************************************** - * \brief returns value for m_artist - * - * If value has not been retrieved from the database, radData() is called first - ****************************************************************************/ string mgGdTrack::getArtist() { if(!m_retrieved) @@ -408,30 +370,24 @@ string mgGdTrack::getArtist() return m_artist; } -/*! - ***************************************************************************** - * \brief returns a string for one field of the item - * - * This is a generic function that shozld work for all content items - ****************************************************************************/ string mgGdTrack::getLabel(int col) { - if(!m_retrieved) + if( !m_retrieved ) { - readData(); + readData(); } - switch(col) + switch(col) { - case 0: - return m_title; - case 1: - return m_artist; - case 2: - return m_album; - case 3: - return m_genre; - default: - return ""; + case 0: + return m_title; + case 1: + return m_artist; + case 2: + return m_album; + case 3: + return m_genre; + default: + return ""; } } @@ -445,27 +401,15 @@ bool mgGdTrack::setTrackInfo(vector<mgFilter*> *info) return false; } -/*! - ***************************************************************************** - * \brief returns value for m_album - * - * If value has not been retrieved from the database, radData() is called first - ****************************************************************************/ string mgGdTrack::getAlbum() { - if(!m_retrieved) + if( !m_retrieved ) { - readData(); + readData(); } - return m_album; + return m_album; } -/*! - ***************************************************************************** - * \brief returns value for m_genre - * - * If value has not been retrieved from the database, radData() is called first - ****************************************************************************/ string mgGdTrack::getGenre() { if(!m_retrieved) @@ -475,12 +419,6 @@ string mgGdTrack::getGenre() return m_genre; } -/*! - ***************************************************************************** - * \brief returns value for m_year - * - * If value has not been retrieved from the database, radData() is called first - ****************************************************************************/ int mgGdTrack::getYear() { if(!m_retrieved) @@ -490,12 +428,6 @@ int mgGdTrack::getYear() return m_year; } -/*! - ***************************************************************************** - * \brief returns value for m_rating - * - * If value has not been retrieved from the database, radData() is called first - ****************************************************************************/ int mgGdTrack::getRating() { if(!m_retrieved) @@ -518,90 +450,36 @@ string mgGdTrack::getImageFile() return "dummyImg.jpg"; } -/*! - ***************************************************************************** - * \brief sets the field for m_title to the specified value - * - * Note: The new value is not stored in the database. - * This is only done, when writeData() is called - ****************************************************************************/ void mgGdTrack::setTitle(string new_title) { m_title = new_title; } -/*! - ***************************************************************************** - * \brief sets the field for m_artist to the specified value - * - * Note: The new value is not stored in the database. - * This is only done, when writeData() is called - ****************************************************************************/ void mgGdTrack::setArtist(string new_artist) { m_artist = new_artist; } - -/*! - ***************************************************************************** - * \brief sets the field for m_album to the specified value - * - * Note: The new value is not stored in the database. - * This is only done, when writeData() is called - ****************************************************************************/ void mgGdTrack::setAlbum(string new_album) { m_album = new_album; } - -/*! - ***************************************************************************** - * \brief sets the field for m_genre to the specified value - * - * Note: The new value is not stored in the database. - * This is only done, when writeData() is called - ****************************************************************************/ void mgGdTrack::setGenre(string new_genre) { m_genre = new_genre; } - -/*! - ***************************************************************************** - * \brief sets the field for m_year to the specified value - * - * Note: The new value is not stored in the database. - * This is only done, when writeData() is called - ****************************************************************************/ void mgGdTrack::setYear(int new_year) { m_year = new_year; } - -/*! - ***************************************************************************** - * \brief sets the field for m_rating to the specified value - * - * Note: The new value is not stored in the database. - * This is only done, when writeData() is called - ****************************************************************************/ void mgGdTrack::setRating(int new_rating) { m_rating = new_rating; } - -/*! - ***************************************************************************** - * \brief stores current values in the sql database - * - * Note: At the moment, only the values stored directly in the 'tracks' - * database are updated - ****************************************************************************/ bool mgGdTrack::writeData() { mgSqlWriteQuery(&m_db, "UPDATE tracks " @@ -612,19 +490,12 @@ bool mgGdTrack::writeData() return true; } -//------------------------------------------------------------------ -//------------------------------------------------------------------ -// -// class GdTracklist -// -//------------------------------------------------------------------ -//------------------------------------------------------------------ GdTracklist::GdTracklist(MYSQL db_handle, string restrictions) { MYSQL_RES *result; MYSQL_ROW row; int trackid; - + result = mgSqlReadQuery(&db_handle, "SELECT tracks.id " " FROM tracks, album, genre WHERE %s" @@ -634,34 +505,15 @@ GdTracklist::GdTracklist(MYSQL db_handle, string restrictions) while((row = mysql_fetch_row(result)) != NULL) { // row[0] is the trackid - if(sscanf(row[0], "%d", &trackid) != 1) + if(sscanf(row[0], "%d", &trackid) != 1) { - mgError("Can not extract integer track id from '%s'", - row[0]); + mgError("Can not extract integer track id from '%s'", + row[0]); } - m_list.push_back(new mgGdTrack(trackid, db_handle)); + m_list.push_back(new mgGdTrack(trackid, db_handle)); } - } - -//------------------------------------------------------------------ -//------------------------------------------------------------------ -// -// class GdPlaylist -// -//------------------------------------------------------------------ -//------------------------------------------------------------------ - -/*! - ***************************************************************************** - * \brief Constructor: opens playlist by name - * - * \param listname user-readable identifier of the paylist - * \param db_handl database which stores the playlist - * - * If the playlist does not yet exist, an empty playlist is created - ****************************************************************************/ GdPlaylist::GdPlaylist(string listname, MYSQL db_handle) { MYSQL_RES *result; @@ -671,14 +523,14 @@ GdPlaylist::GdPlaylist(string listname, MYSQL db_handle) m_db = db_handle; // - // check, if the database really exists + // check, if the playlist already exists // - result=mgSqlReadQuery(&m_db, - "SELECT id,author FROM playlist where title=\"%s\"", - listname.c_str()); + result = mgSqlReadQuery(&m_db, + "SELECT id,author FROM playlist where title=\"%s\"", + listname.c_str()); nrows = mysql_num_rows(result); - if(nrows == 0) - { + if( nrows == 0 ) + { mgDebug(3, "No playlist with name %s found. Creating new playlist\n", listname.c_str()); @@ -692,55 +544,47 @@ GdPlaylist::GdPlaylist(string listname, MYSQL db_handle) 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()); + 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]); - } + { + 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]); - } + { + 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) - + }// end 'else (playlist exists) + m_listtype = GD_PLAYLIST_TYPE; // GiantDB list type for playlists } -/*! - ***************************************************************************** - * \brief empty destructor - * - * Nothing to be done. Constructor of parent class takes care - ****************************************************************************/ GdPlaylist::~GdPlaylist() { } + void GdPlaylist::setListname(std::string name) { m_listname = name; m_sqlId = -1; } -/*! - ***************************************************************************** - * \brief reads the track list from the sql database into a locallist - ****************************************************************************/ + int GdPlaylist::insertDataFromSQL() { MYSQL_RES *result; @@ -1436,6 +1280,9 @@ mgContentItem* GdTreeNode::getSingleTrack() /* -------------------- begin CVS log --------------------------------- * $Log: gd_content_interface.c,v $ + * Revision 1.27 2004/08/30 14:31:43 LarsAC + * Documentation added + * * Revision 1.26 2004/08/27 15:19:34 LarsAC * Changed formatting and documentation * diff --git a/gd_content_interface.h b/gd_content_interface.h index 7d43d74..5d2626b 100644 --- a/gd_content_interface.h +++ b/gd_content_interface.h @@ -3,8 +3,8 @@ * \brief Data objects for content (e.g. mp3 files, movies) * for the vdr muggle plugin database * - * \version $Revision: 1.10 $ - * \date $Date: 2004/08/27 15:19:34 $ + * \version $Revision: 1.11 $ + * \date $Date: 2004/08/30 14:31:43 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner * \author Responsible author: $Author: LarsAC $ * @@ -53,6 +53,9 @@ class gdFilterSets : public mgFilterSets public: + /*! \addtogroup Object creation and destruction */ + /*\@{*/ + /*! * \brief the default constructor * @@ -66,6 +69,8 @@ class gdFilterSets : public mgFilterSets */ virtual ~gdFilterSets(); + /*\@}*/ + /*! * \brief compute restriction w.r.t active filters * @@ -95,6 +100,9 @@ class mgGdTrack : public mgContentItem { public: + /*! \addtogroup Object creation and destruction */ + /*\@{*/ + /*! * \brief a constructor * @@ -128,9 +136,22 @@ class mgGdTrack : public mgContentItem * \brief the destructor */ virtual ~mgGdTrack(); + + /*\@}*/ - virtual mgContentItem::contentType getContentType(){return mgContentItem::GD_AUDIO;} + /*! + * \brief obtain the content type of the item + */ + virtual mgContentItem::contentType getContentType() + { + return mgContentItem::GD_AUDIO; + } + /*! + * \brief obtain the associated player object + * + * \todo what is this used for? + */ virtual mgMediaPlayer getPlayer() { return mgMediaPlayer(); @@ -138,42 +159,129 @@ class mgGdTrack : public mgContentItem /*! \addtogroup Data read access */ /*\@{*/ + + /*! + * \brief returns a certain field of the item as a string + * + * 0 - title + * 1 - artist + * 2 - album + * 3 - genre + */ virtual std::string getLabel( int col = 0 ); + /*! + * \brief returns value for the track title + */ virtual std::string getTitle(); + + /*! + * \brief returns value for the location of the track on disk + */ virtual std::string getSourceFile(); + + /*! + * \brief returns the genre of the track + */ virtual std::string getGenre(); + + /*! + * \brief returns the artist of the track + */ std::string getArtist(); + + /*! + * \brief returns value the album to which the track belongs + */ std::string getAlbum(); + + /*! + * \brief obtain the location of the image file + */ std::string getImageFile(); + + /*! + * \brief obtain the year of the track + */ int getYear(); + + /*! + * \brief obtain the duration of the track + */ int getDuration(); + + /*! + * \brief obtain the rating of the track + */ virtual int getRating(); + /*! + * \brief obtain the complete track information + */ virtual std::vector<mgFilter*> *getTrackInfo(); + /*\@}*/ /*! \addtogroup Data write access */ /*\@{*/ + + /*! + * \brief set the title of the track + */ void setTitle(std::string new_title); + + /*! + * \brief set the title of the track + */ void setArtist(std::string new_artist); + + /*! + * \brief set the album name of the track + */ void setAlbum(std::string new_album); + + /*! + * \brief set the genre of the track + */ void setGenre(std::string new_genre); - void setYear(int new_rating); + + /*! + * \brief set the year of the track + */ + void setYear(int new_year); + + /*! + * \brief set the rating of the track + */ void setRating(int new_rating); + /*! + * \brief set complete information of the track + */ virtual bool setTrackInfo(std::vector<mgFilter*>*); + /*! + * \brief make changes persistent + * + * The changes made using the setXxx methods are not + * stored persistently in the database until writeData + * is called. + * + * \note only the tracks table in the SQL database is updated. + * Genre and album field information is lost. + */ bool writeData(); + /*\@}*/ - + + //! \brief a special instance denoting an undefined track static mgGdTrack UNDEFINED; private: /*! * \brief the database in which the track resides - * */ + */ MYSQL m_db; /*! @@ -185,7 +293,9 @@ private: */ bool m_retrieved; - //! \brief the artist name + /*! + * \brief the artist name + */ std::string m_artist; /*! @@ -225,16 +335,25 @@ private: int m_length; /*! - * \brief Access the data of the item from the database + * \brief Access the data of the item from the database and fill actual data fields + * + * In order to avoid abundant queries to the database, the content fields + * of the mgGdTrack object may not be filled upon creation. As soon as the + * first content field is needed, this private function is called to fill + * all content fields at once. */ bool readData(); }; +/* + * \brief a list of tracks stored in the databas + */ class GdTracklist : public mgTracklist { public: - GdTracklist(MYSQL db_handle, std::string restrictions); + + GdTracklist(MYSQL db_handle, std::string restrictions); }; /*! @@ -246,29 +365,67 @@ class GdPlaylist : public mgPlaylist { public: + /*! \addtogroup Object creation and destruction */ + /*\@{*/ + + /*! + * \brief opens an existing or creates empty playlist by name + * + * If the playlist does not yet exist, an empty playlist is created. + * + * \param listname - user-readable identifier of the paylist + * \param db_handle - database which stores the playlist + */ GdPlaylist(std::string listname, MYSQL db_handle); - /* opens existing or creates empty playlist */ - + + /*! + * \brief destructor + * + * \note the destructor only destroys the in-memory footprint of the playlist, + * it does not modify the database. + */ virtual ~GdPlaylist(); + + /* \@} */ + /*! + * changes the listname of the playlist (and unset the sql id) + */ virtual void setListname(std::string name); - /* changes the listname of the playlist (and unset the sql id */ + /*! + * returns the total duration of all songs in the list in seconds + */ int getPlayTime(); - /* returns the total duration of all songs in the list in seconds */ + /*! + * returns the duration of all remaining songs in the list in seconds + */ int getPlayTimeRemaining(); - /* returns the duration of all remaining songs in the list in seconds */ - + + /*! + * \brief write data back to the database + */ bool storePlaylist(); private: - int m_sqlId; /* -1 means: not valid */ - int m_listtype; // used in GiantDisc db queries + + /*! + * \brief reads the track list from the sql database into memory + */ + int insertDataFromSQL(); + + //! \brief the database identifier of the list + int m_sqlId; + + //! \brief the list type used in GiantDisc db queries + int m_listtype; + + //! \brief the author of the playlist std::string m_author; - MYSQL m_db; - int insertDataFromSQL(); + //! \brief the handle to the database in which the list is stored + MYSQL m_db; }; /*! @@ -283,29 +440,62 @@ class GdPlaylist : public mgPlaylist * Each child inherits the restrictions of its father and an additional * restriction on the recently expanded db field */ -class GdTreeNode : public mgSelectionTreeNode +class GdTreeNode : public mgSelectionTreeNode { public: - /*==== constructors ====*/ - GdTreeNode(MYSQL db, int view, std::string filters); // top level - GdTreeNode(mgSelectionTreeNode* parent, - std::string id, std::string label, std::string restriction); + /*! \addtogroup Object creation and destruction */ + /*\@{*/ + + /*! + * \brief Construct a top level tree node in a certain view with certain filters + */ + GdTreeNode(MYSQL db, int view, std::string filters); - /*==== destructor ====*/ - virtual ~GdTreeNode(); + /*! + * \brief Construct a subordinate tree node with given labels and restrictions + */ + GdTreeNode(mgSelectionTreeNode* parent, + std::string id, std::string label, std::string restriction); + + /*! + * \brief destructor to clean up the object + */ + virtual ~GdTreeNode(); - // compute children on the fly - virtual bool isLeafNode(); - virtual bool expand(); + /* \@} */ - // access data in current node - virtual std::vector<mgContentItem*>* getTracks(); - virtual mgContentItem* getSingleTrack(); + /*! \addtogroup Access node data */ + /*\@{*/ + + /*! + * \brief check, whether the node is a leaf node (i.e. has no more children) + */ + virtual bool isLeafNode(); + + /*! + * \brief expand the node and generate child nodes according to restrictions passed in the constructor + */ + virtual bool expand(); + + /*! + * \brief obtain the tracks in this node + */ + virtual std::vector<mgContentItem*>* getTracks(); + + /*! + * \brief obtain a single track in this node + */ + virtual mgContentItem* getSingleTrack(); + + /* \@} */ }; /* -------------------- begin CVS log --------------------------------- * $Log: gd_content_interface.h,v $ + * Revision 1.11 2004/08/30 14:31:43 LarsAC + * Documentation added + * * Revision 1.10 2004/08/27 15:19:34 LarsAC * Changed formatting and documentation * @@ -1,25 +1,29 @@ -/*******************************************************************/ /*! \file muggle_tools.h - * \brief A few util functions for standalone and plugin messaging - * for the vdr muggle plugindatabase - ******************************************************************** - * \version $Revision: 1.3 $ - * \date $Date: 2004/05/28 15:29:18 $ + * \brief A few utility functions for standalone and plugin messaging for the vdr muggle plugindatabase + * + * \version $Revision: 1.4 $ + * \date $Date: 2004/08/30 14:31:43 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner - * \author file owner: $Author: lvw $ + * \author file owner: $Author: LarsAC $ * */ -/*******************************************************************/ -/* makes sur we dont use parse the same declarations twice */ + +/* makes sure we don't use the same declarations twice */ #ifndef _MUGGLE_TOOLS_H #define _MUGGLE_TOOLS_H #include <iostream> #include <string> +#include <mysql/mysql.h> + +#define STANDALONE 1 // what's this? + +// mySql helper functions -#include "mysql/mysql.h" +MYSQL_RES* mgSqlReadQuery( MYSQL *db, const char *fmt, ... ); +void mgSqlWriteQuery( MYSQL *db, const char *fmt, ... ); -#define STANDALONE 1 +// Messaging functions void mgSetDebugLevel(int new_level); void mgDebug(int level, const char *fmt, ...); @@ -27,9 +31,6 @@ void mgDebug( const char *fmt, ... ); void mgWarning(const char *fmt, ...); void mgError(const char *fmt, ...); -MYSQL_RES* mgSqlReadQuery(MYSQL *db, const char *fmt, ...); -void mgSqlWriteQuery(MYSQL *db, const char *fmt, ...); - #ifdef DEBUG #define MGLOG(x) mgLog __thelog(x) #else @@ -42,7 +43,6 @@ void mgSqlWriteQuery(MYSQL *db, const char *fmt, ...); #define MGLOGSTREAM __thelog.getStream() #endif - class mgLog { public: @@ -74,6 +74,9 @@ class mgLog /* -------------------- begin CVS log --------------------------------- * $Log: mg_tools.h,v $ + * Revision 1.4 2004/08/30 14:31:43 LarsAC + * Documentation added + * * Revision 1.3 2004/05/28 15:29:18 lvw * Merged player branch back on HEAD branch. * |