listtests.cpp

Example2 - listtests.cpp showing listing of tracks, playlist and creating smart playlists

00001 /***************************************************************************
00002  *   Copyright (C) 2006 by Michael Schulze   *
00003  *   mike.s@genion.de   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 
00022 #include <stdio.h>
00023 #include <qfile.h>
00024 #include <qstringlist.h>
00025 
00026 #include <qobject.h>
00027 
00028 #include "listtests.h"
00029 
00030 #include "ipod.h"
00031 
00032 
00033 
00034 #define RECENTLYPLAYEDTITLE "KPOD:Recently Played"
00035 #define RECENTLYSKIPPEDTITLE "KPOD:Recently Skipped"
00036 #define RECENTLYADDEDTITLE "KPOD:Recently added"
00037 #define FAVORITES "KPOD:Most Played"
00038 #define NEVERPLAYEDBEFORETITLE "KPOD:Never Played Before"
00039 #define HIGHESTRATEDLIST "KPOD:Highest Rated"
00040 
00041 using namespace itunesdb;
00042 
00043 /**
00044  * Creates a smart playlist with a rule for the matching the songs played in
00045  * the last 2 weeks and a limit for the 30 last played songs.
00046  */
00047 void ListTests::createRecentlyPlayedList( ITunesDB& itunesdb ) {
00048     printf( "creating new smart playlist: %s\n", RECENTLYPLAYEDTITLE );
00049 
00050     // create a new playlist
00051     ITunesDBPlaylist * recentlyPlayed = itunesdb.createNewPlaylist( RECENTLYPLAYEDTITLE );
00052 
00053     recentlyPlayed->setSortOrder( Playlist::SORTORDER_TIME_PLAYED );
00054 
00055     // make it a smart playlist and get the ruleset
00056     SmartPlaylistRuleSet& ruleSet = recentlyPlayed->enableSmartPlaylist();
00057 
00058     // add the rule "last played in the last 2 weeks"
00059     ruleSet.addInTheLastRule( FIELD_LASTPLAYED, false, -2, IN_THE_LAST_WEEKS );
00060 
00061     // limit to the first 30 songs, sorted by last played date
00062     ruleSet.setLimits( LIMIT_SORT_LASTPLAYED, LIMIT_TYPE_SONGS, 30 );
00063 
00064     // match ANY rule (doesn't really matter since we only have one rule)
00065     ruleSet.setMatchAnyFlag( true );
00066 
00067     // enable live update (updates the playlist on the go)
00068     ruleSet.setLiveUpdateFlag( true );
00069 
00070     // finally add the playlist to the database
00071     if ( !itunesdb.addPlaylist( recentlyPlayed ) ) {
00072         delete recentlyPlayed;
00073     }
00074 }
00075 
00076 /**
00077  * Creates a smart playlist with a rule for the matching the songs played in
00078  * the last 2 weeks and a limit for the 30 last played songs.
00079  */
00080 void ListTests::createRecentlySkippedList( ITunesDB& itunesdb ) {
00081     printf( "creating new smart playlist: %s\n", RECENTLYSKIPPEDTITLE );
00082 
00083     // create a new playlist
00084     ITunesDBPlaylist * recentlySkipped = itunesdb.createNewPlaylist( RECENTLYSKIPPEDTITLE );
00085 
00086     recentlySkipped->setSortOrder( Playlist::SORTORDER_TIME_PLAYED );
00087 
00088     // make it a smart playlist and get the ruleset
00089     SmartPlaylistRuleSet& ruleSet = recentlySkipped->enableSmartPlaylist();
00090 
00091     // add the rule "last played in the last 2 weeks"
00092     ruleSet.addInTheLastRule( FIELD_LAST_SKIPPED, false, -2, IN_THE_LAST_WEEKS );
00093 
00094     // limit to the first 30 songs, sorted by last played date
00095     ruleSet.setLimits( LIMIT_SORT_LASTPLAYED, LIMIT_TYPE_SONGS, 30 );
00096 
00097     // match ANY rule (doesn't really matter since we only have one rule)
00098     ruleSet.setMatchAnyFlag( true );
00099 
00100     // enable live update (updates the playlist on the go)
00101     ruleSet.setLiveUpdateFlag( true );
00102 
00103     // finally add the playlist to the database
00104     if ( !itunesdb.addPlaylist( recentlySkipped ) ) {
00105         delete recentlySkipped;
00106     }
00107 }
00108 
00109 
00110 /**
00111  * Creates a smart playlist for the 25 most often played tracks
00112  */
00113 void ListTests::createTop25List( ITunesDB& itunesdb ) {
00114     printf( "creating new smart playlist: %s\n", FAVORITES );
00115 
00116     // create a new playlist
00117     ITunesDBPlaylist * favorites = itunesdb.createNewPlaylist( FAVORITES );
00118 
00119     // sort by playcount
00120     favorites->setSortOrder( ITunesDBPlaylist::SORTORDER_PLAYCOUNT );
00121 
00122     // make it a smart playlist and get the ruleset
00123     SmartPlaylistRuleSet& ruleSet = favorites->enableSmartPlaylist();
00124 
00125     // only tracks that were played at least once
00126     ruleSet.addUIntRule( itunesdb::FIELD_PLAYCOUNT, itunesdb::ACTION_GREATER_THAN, 0, 0 );
00127 
00128     // limit to the 25 most played songs
00129     ruleSet.setLimits( LIMIT_SORT_PLAYCOUNT, LIMIT_TYPE_SONGS, 25 );
00130 
00131     // enable live update (updates the playlist on the go)
00132     ruleSet.setLiveUpdateFlag( true );
00133 
00134     // finally add the playlist to the database
00135     if ( !itunesdb.addPlaylist( favorites ) ) {
00136         delete favorites;
00137     }
00138 
00139 }
00140 
00141 
00142 void ListTests::createNeverPlayedBeforeList( ITunesDB& itunesdb ) {
00143     printf( "creating new smart playlist: %s\n", NEVERPLAYEDBEFORETITLE );
00144 
00145     // create a new playlist
00146     ITunesDBPlaylist * neverplayed = itunesdb.createNewPlaylist( NEVERPLAYEDBEFORETITLE );
00147 
00148     neverplayed->setSortOrder( itunesdb::Playlist::SORTORDER_TIME_ADDED );
00149 
00150     SmartPlaylistRuleSet& ruleSet = neverplayed->enableSmartPlaylist();
00151     ruleSet.setMatchAnyFlag( false );
00152     ruleSet.addUIntRule( FIELD_LASTPLAYED, ACTION_IS_UINT, 0, 0 );
00153     ruleSet.addUIntRule( FIELD_LAST_SKIPPED, ACTION_IS_UINT, 0, 0 );
00154     ruleSet.setLimits( LIMIT_SORT_RECENTLYADDED, LIMIT_TYPE_SONGS, 50, true );
00155     ruleSet.setLiveUpdateFlag( true );
00156 
00157     if ( !itunesdb.addPlaylist( neverplayed ) ) {
00158         delete neverplayed;
00159     }
00160 }
00161 
00162 
00163 void ListTests::createHighestRated( ITunesDB& itunesdb ) {
00164     printf( "creating new smart playlist: %s\n", HIGHESTRATEDLIST );
00165 
00166     // create a new playlist
00167     ITunesDBPlaylist * highestrated = itunesdb.createNewPlaylist( HIGHESTRATEDLIST );
00168 
00169     highestrated->setSortOrder( itunesdb::Playlist::SORTORDER_RANDOM );
00170 
00171     SmartPlaylistRuleSet& ruleSet = highestrated->enableSmartPlaylist();
00172     ruleSet.setMatchAnyFlag( false );
00173     ruleSet.addUIntRule( itunesdb::FIELD_RATING, ACTION_IS_UINT, 100, 100 );
00174     ruleSet.setLiveUpdateFlag( true );
00175 
00176     if ( !itunesdb.addPlaylist( highestrated ) ) {
00177         delete highestrated;
00178     }
00179 }
00180 
00181 
00182 /**
00183  * Creates a playlist with the tracks added in the last 2 weeks
00184  */
00185 void ListTests::createNewestAdditionsList( ITunesDB& itunesdb ) {
00186     printf( "creating new smart playlist: %s\n", RECENTLYADDEDTITLE );
00187 
00188     // create a new playlist
00189     ITunesDBPlaylist * recentlyAdded = itunesdb.createNewPlaylist( RECENTLYADDEDTITLE );
00190 
00191     // sort the playlist by artist
00192     recentlyAdded->setSortOrder( itunesdb::Playlist::SORTORDER_ARTIST );
00193 
00194     // make it smart and get a reference to the still empty ruleset
00195     SmartPlaylistRuleSet& ruleSet = recentlyAdded->enableSmartPlaylist();
00196 
00197     // add a rule matching all the tracks added in the last 2 weeks
00198     ruleSet.addInTheLastRule( FIELD_DATEADDED, false, -2, IN_THE_LAST_WEEKS );
00199 
00200     // enable live update
00201     ruleSet.setLiveUpdateFlag( true );
00202 
00203     // add the playlist to the database
00204     if ( !itunesdb.addPlaylist( recentlyAdded ) ) {
00205         delete recentlyAdded;
00206     }
00207 
00208 }
00209 
00210 
00211 /**
00212  * Prints the contents of a playlist in the desired order to stdout.
00213  */
00214 void ListTests::printSortedBy( ITunesDBPlaylist& playlist, Playlist::Sortorder order ) {
00215     // save the old sort order
00216     Playlist::Sortorder origOrder = playlist.getSortOrder();
00217     // set the desired order
00218     playlist.setSortOrder( order );
00219 
00220     // iterate over the playlist
00221     Playlist::Iterator trackIter = playlist.getElements();
00222     while( trackIter.hasNext() ) {
00223         Track * track = playlist.getTrack( *trackIter.next() );
00224 
00225         if ( track ) {
00226             fprintf( stdout, "\t%s\t\t%d,%d\t\t%s\t\t%s\n",
00227                     track->getArtist().ascii(), track->getPlayCount(), track->getSkipCount(), track->getAlbum().ascii(), track->getTitle().ascii() );
00228         } else {
00229             // this only happens if the database is inconsistent
00230             // this will be fixed when saving back the database
00231             fprintf( stdout, "\ttrack not found\n" );
00232         }
00233     }
00234 
00235     // restore the original sort order
00236     playlist.setSortOrder( origOrder );
00237 }
00238 
00239 
00240 /**
00241  * This rather inefficient but informative example prints out all the tracks grouped by
00242  * artist and album, giving lots of examples on how to query the database for various information
00243  * 
00244  * A more efficient way to do this would be to create a sorted TrackPtrList and iterate over it
00245  * printing Artist and Album every time it changes
00246  */
00247 void ListTests::printTracksByArtist( const ITunesDB& itunesdb ) {
00248     // get a list of all artist names
00249     QStringList artistlist;
00250     if( !itunesdb.getArtists( artistlist ) ) {
00251         printf("NO ARTISTS!!!!");
00252     }
00253 
00254     // iterate over the artist names
00255     for( QStringList::iterator artistiterator = artistlist.begin(); artistiterator!= artistlist.end(); ++artistiterator ) {
00256         // print out the artist
00257         printf("%s\n", (*artistiterator).ascii());
00258 
00259 
00260         // get a list of albums by the artist
00261         QStringList albums;
00262         if( ! itunesdb.getAlbumsByArtist( *artistiterator, albums ) ) {
00263             // doesn't happen
00264             printf("ARTIST NOT FOUND!!!");
00265         } else {
00266             QStringList::iterator albumiterator = albums.begin();
00267             for( ; albumiterator != albums.end(); ++albumiterator) {
00268 
00269                 // get the tracks in the album
00270                 TrackPtrList album;
00271                 // get the album by artistname, albumname
00272                 itunesdb.getAlbum( *artistiterator, *albumiterator, album );
00273                 // sort by default sort order (track number)
00274                 album.sort();
00275 
00276                 // print out the albumname, number of tracks and if a track
00277                 // of the album was played recently
00278                 printf("\t%s (%d)%s\n", (*albumiterator).ascii(), album.count(), album.hasRecentlyPlayedTracks() ? " played recently" : "");
00279 
00280                 // iterate over the tracks
00281                 TrackPtrList::Iterator trackiterator = album.iterator();
00282                 while ( trackiterator.hasNext() ) {
00283                     itunesdb::Track * track = trackiterator.next();
00284 
00285                     QDateTime added;
00286                     added.setTime_t( track->getDateAdded(), Qt::UTC );
00287 
00288                     QDateTime played;
00289                     played.setTime_t( track->getLastPlayed(), Qt::UTC );
00290 
00291                     // print out number and title, last played date and
00292                     // the date the track was added to the database
00293                     printf("\t\t%d - %s - played %s, added %s\n",
00294                         track->getTrackNumber(), track->getTitle().ascii(),
00295                         played.toString().ascii(), added.toString().ascii() );
00296                 }
00297             }
00298             printf("\tall Tracks ...\n");
00299 
00300 
00301             /******************************************************************
00302             *
00303             * list all the tracks by the given artist, regardless of the album
00304             *
00305             *****************************************************************/
00306 
00307             // list all the tracks by the artist
00308             TrackPtrList artisttracks;
00309             // get all the tracks by the given artistname
00310             itunesdb.getTracksByArtist( *artistiterator, artisttracks );
00311 
00312             // sort the tracks by album
00313             artisttracks.setComparator( TrackComparators::BY_ALBUM );
00314             artisttracks.sort();
00315 
00316             TrackPtrList::Iterator trackiterator = artisttracks.iterator();
00317             while ( trackiterator.hasNext() ) {
00318                 itunesdb::Track * track = trackiterator.next();
00319                 printf("\t\t%s - %d - %s\n", track->getAlbum().ascii(), track->getTrackNumber(), track->getTitle().ascii());
00320             }
00321         }
00322     }
00323 }
00324 
00325 /**
00326  * Print out all the playlists.
00327  */
00328 void ListTests::printPlaylists( const ITunesDB& itunesdb ) {
00329 
00330     // get all the playlist titles
00331     QStringList playlistTitles;
00332     itunesdb.getPlaylistTitles( playlistTitles );
00333 
00334     fprintf( stdout, "PLAYLISTS\n" );
00335 
00336     // iterate over all the playlists
00337     for ( unsigned int i = 0; i < playlistTitles.count(); ++i ) {
00338         ITunesDBPlaylist * playlist = itunesdb.getPlaylistByTitle( playlistTitles[ i ] );
00339 
00340         if ( playlist ) {   // would be weird if not, but who knows
00341             if ( playlist->isSmartPlaylist() ) {
00342                 // print out the ruleset
00343                 fprintf( stdout, "%s\n", playlist->getSmartPlaylistRules()->toString().ascii() );
00344 
00345                 // forced update of the playlists entries
00346                 playlist->updateSmartPlaylist( true );
00347             }
00348 
00349             fprintf( stdout, "%s (%d) - original order\n", playlist->getTitle().ascii(), playlist->getNumTracks() );
00350             printSortedBy( *playlist, playlist->getSortOrder() );
00351 
00352             fprintf( stdout, "%s - ordered by title\n", playlist->getTitle().ascii() );
00353             printSortedBy( *playlist, Playlist::SORTORDER_TITLE );
00354 
00355             fprintf( stdout, "%s - ordered by artist\n", playlist->getTitle().ascii() );
00356             printSortedBy( *playlist, Playlist::SORTORDER_ARTIST );
00357 
00358             fprintf( stdout, "%s - randomly\n", playlist->getTitle().ascii() );
00359             printSortedBy( *playlist, Playlist::SORTORDER_RANDOM );
00360 
00361             fprintf( stdout, "%s - ordered by time played\n", playlist->getTitle().ascii() );
00362             printSortedBy( *playlist, Playlist::SORTORDER_PLAYCOUNT );
00363         }
00364     }
00365 
00366     printf( "number of playlists: %u\n", itunesdb.getNumPlaylists() );
00367 }
00368 
00369 
00370 int ListTests::run( QStringList arguments ) {
00371     IPod * ipod = findFirstIPod();
00372     if ( !ipod ) {
00373         return -1;
00374     }
00375 
00376     // get the iTunesDB instance
00377     ITunesDB& itunesdb = ipod->getITunesDB();
00378 
00379     // print out all the tracks
00380     printTracksByArtist( itunesdb );
00381 
00382     // test smart playlist stuff
00383 
00384     ITunesDBPlaylist * spl = itunesdb.getPlaylistByTitle( RECENTLYPLAYEDTITLE );
00385     if ( spl == NULL ) {
00386         createRecentlyPlayedList( itunesdb );
00387     }
00388 
00389     spl = itunesdb.getPlaylistByTitle( FAVORITES );
00390     if ( spl == NULL ) {
00391         createTop25List( itunesdb );
00392     }
00393 
00394     spl = itunesdb.getPlaylistByTitle( NEVERPLAYEDBEFORETITLE );
00395     if ( spl == NULL ) {
00396         createNeverPlayedBeforeList( itunesdb );
00397     }
00398 
00399     spl = itunesdb.getPlaylistByTitle( RECENTLYADDEDTITLE );
00400     if ( spl == NULL ) {
00401         createNewestAdditionsList( itunesdb );
00402     }
00403 
00404     spl = itunesdb.getPlaylistByTitle( RECENTLYSKIPPEDTITLE );
00405     if ( spl == NULL ) {
00406         createRecentlySkippedList( itunesdb );
00407     }
00408 
00409     spl = itunesdb.getPlaylistByTitle( HIGHESTRATEDLIST );
00410     if ( spl == NULL ) {
00411         createHighestRated( itunesdb );
00412     }
00413 
00414     printPlaylists( itunesdb );
00415 
00416     printf( "%s is %s\n", ipod->getName().ascii(), ipod->isDirty() ? "dirty" : "clean" );
00417 
00418     // try to write
00419 #ifdef WIN32
00420     ipod->getITunesDB().writeDatabase( "c:/iTunesDB" );
00421 #else
00422     ipod->getITunesDB().writeDatabase( "/tmp/iTunesDB" );
00423 #endif
00424     printf("closing ipod instance\n");
00425     ipod->close();
00426     delete ipod;
00427 
00428     return 0;
00429 }
00430 
00431 QString ListTests::getName() {
00432     return "list";
00433 }
00434 
00435 

Generated on Wed Nov 28 03:04:37 2007 for libqtpod by  doxygen 1.5.0